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程序设计有所帮助。