python:实现socket桥接转发
dvr项目中flex驻留在浏览器,而影响播放程序是独立的进程,sandbox的安全问题导致flex的代码无法直接与播放进程IPC通信,那只有通过公网IP的主机进行桥接。
很多年以前用过foundstone系列的工具,也有socket转向的功能,包括在5173时做过lsp的底层转向软件(仿sockcap),原理当然是相当简单,python是首选工具。
代码接收两端建立socket进来,并根据相同的id号来进行socket配对,之后两个socket之间就实现互相转发(技术同之前写的http代理服务器 )
1 # -- coding:utf-8 --
2
3 import socket,traceback,os,os.path,sys,time,struct,base64,gzip,array,threading
4 import select,json
5
6
7 '''
8 {'id','type'}
9
10 type - 'mapshow','imageplay'
11 id - 一次会话的编号
12
13 imageplay 与xbridge建立socket连接,并注册一个会话编号(随机产生)
14 imageplay启动mapshow,并将会话编号传递给mapshow,mapshow建立xbridge的连接,并提交会话编号
15 xbridge将双向传递相同会话编号的数据到对方
16
17 sock1的客户必须等sock2连接进入之后发送数据,否则将sock1数据转发给sock2时将产生异常
18 '''
19
20 class ConnectionPair:
21 def __init__(self,app):
22 self.app = app
23 self.id = ''
24 self.sock1=None #imageplay上来的连接
25 self.sock2=None #第二个连接上来的对象mapdemo
26
27 def start(self):
28 t = threading.Thread(target=self.threadRecv)
29 t.start()
30
31 def onLostConnection(self):
32 try:
33 print 'connection pair lost..'
34 self.sock1.close()
35 self.sock2.close()
36 self.app.onConnectionPairBroken(self)
37 except:
38 traceback.print_exc()
39
40 def threadRecv(self):
41 print 'service threading entering '
42 import select
43 while True:
44 fds = []
45 if self.sock1:
46 fds.append(self.sock1)
47 if self.sock2:
48 fds.append(self.sock2)
49 #fds = [self.sock1,self.sock2]
50 try:
51 #sock2未连接进来前,将不接收sock1上产生数据
52 #print 'fds:',len(fds),fds
53 rds,wds,eds = select.select(fds,[],[],1)
54 if not rds:#timeout
55 continue
56
57 for s in rds:
58 d = s.recv(1024)
59 #print d
60 if not d:
61 raise 'any jump'
62
63 to = self.sock2
64 if s == self.sock2:
65 to = self.sock1
66 #print 'redirect data:',d
67 to.sendall(d)
68 except:
69 traceback.print_exc()
70 self.onLostConnection()
71 break
72
73 print 'ConnThread Exiting '
74
75
76
77
78 class XBridge:
79 def __init__(self,addr=('',12788)):
80 self.sock = None
81 self.addr = addr
82 self.conns={} #{id}
83 self.mtxconns = threading.Lock()
84 &
补充:Web开发 , Python ,