python实现简单的TCP代理服务器
本文实例讲述了python实现简单的TCP代理服务器的方法,分享给大家供大家参考。
具体实现代码如下:
#-*-coding:utf-8-*- ''' filename:rtcp.py @desc: 利用python的socket端口转发,用于远程维护 如果连接不到远程,会sleep36s,最多尝试200(即两小时) @usage: ./rtcp.pystream1stream2 stream为:l:port或c:host:port l:port表示监听指定的本地端口 c:host:port表示监听远程指定的端口 @author:watercloud,zd,knownsecteam @web:www.knownsec.com,blog.knownsec.com @date:2009-7 ''' importsocket importsys importthreading importtime streams=[None,None]#存放需要进行数据转发的两个数据流(都是SocketObj对象) debug=1#调试状态0or1 def_usage(): print'Usage:./rtcp.pystream1stream2\nstream:l:portorc:host:port' def_get_another_stream(num): ''' 从streams获取另外一个流对象,如果当前为空,则等待 ''' ifnum==0: num=1 elifnum==1: num=0 else: raise"ERROR" whileTrue: ifstreams[num]=='quit': print("can'tconnecttothetarget,quitnow!") sys.exit(1) ifstreams[num]!=None: returnstreams[num] else: time.sleep(1) def_xstream(num,s1,s2): ''' 交换两个流的数据 num为当前流编号,主要用于调试目的,区分两个回路状态用。 ''' try: whileTrue: #注意,recv函数会阻塞,直到对端完全关闭(close后还需要一定时间才能关闭,最快关闭方法是shutdow) buff=s1.recv(1024) ifdebug>0: printnum,"recv" iflen(buff)==0:#对端关闭连接,读不到数据 printnum,"oneclosed" break s2.sendall(buff) ifdebug>0: printnum,"sendall" except: printnum,"oneconnectclosed." try: s1.shutdown(socket.SHUT_RDWR) s1.close() except: pass try: s2.shutdown(socket.SHUT_RDWR) s2.close() except: pass streams[0]=None streams[1]=None printnum,"CLOSED" def_server(port,num): ''' 处理服务情况,num为流编号(第0号还是第1号) ''' srv=socket.socket(socket.AF_INET,socket.SOCK_STREAM) srv.bind(('0.0.0.0',port)) srv.listen(1) whileTrue: conn,addr=srv.accept() print"connectedfrom:",addr streams[num]=conn#放入本端流对象 s2=_get_another_stream(num)#获取另一端流对象 _xstream(num,conn,s2) def_connect(host,port,num): '''处理连接,num为流编号(第0号还是第1号) @note:如果连接不到远程,会sleep36s,最多尝试200(即两小时) ''' not_connet_time=0 wait_time=36 try_cnt=199 whileTrue: ifnot_connet_time>try_cnt: streams[num]='quit' print('notconnected') returnNone conn=socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: conn.connect((host,port)) exceptException,e: print('cannotconnect%s:%s!'%(host,port)) not_connet_time+=1 time.sleep(wait_time) continue print"connectedto%s:%i"%(host,port) streams[num]=conn#放入本端流对象 s2=_get_another_stream(num)#获取另一端流对象 _xstream(num,conn,s2) if__name__=='__main__': iflen(sys.argv)!=3: _usage() sys.exit(1) tlist=[]#线程列表,最终存放两个线程对象 targv=[sys.argv[1],sys.argv[2]] foriin[0,1]: s=targv[i]#stream描述c:ip:port或l:port sl=s.split(':') iflen(sl)==2and(sl[0]=='l'orsl[0]=='L'):#l:port t=threading.Thread(target=_server,args=(int(sl[1]),i)) tlist.append(t) eliflen(sl)==3and(sl[0]=='c'orsl[0]=='C'):#c:host:port t=threading.Thread(target=_connect,args=(sl[1],int(sl[2]),i)) tlist.append(t) else: _usage() sys.exit(1) fortintlist: t.start() fortintlist: t.join() sys.exit(0)
完整实例代码点击此处本站下载。
希望本文所述对大家的Python程序设计有所帮助。