python编写网络通信框架-基于线程的消息传送. 消息格式定义
1
#
-- coding:utf-8 --
2
3 import socket,traceback,os,os.path,sys,time,struct,base64,gzip,array,json,zlib
4
5 '''
6 ------------------
7 msghdr
8 cmdtxt
9 \0\0
10 二进制流
11 -----------------
12 视频包由三部分构成: MetaMessage数据元封套,控制命令文本(json格式),二进制数据,后两者之间采用连续两个\0区分,表示开始二进制流数据
13 [metamsg,cmdtxt,bindata]
14 bindata部分格式、编码由cmdtxt控制
15
16 # [magic,size,compress,encrypt,version],[command text(json)],[\0\0],[binary data..]
17 '''
18
19 COMPRESS_NONE = 0
20 COMPRESS_ZLIB = 1
21 COMPRESS_BZIP2 = 2
22
23 ENCRYPT_NONE = 0
24 ENCRYPT_MD5 = 1
25 ENCRYPT_DES = 2
26
27
28 class MessageBase:
29 def __init__ (self,type = '' ,bin = None):
30 # self.type = type
31 self.attrs = { ' msg ' :type}
32 self.bin = bin
33
34 def getMsg(self):
35 return self.getValue( ' msg ' )
36
37 def getValue(self,key):
38 if self.attrs.has_key(key):
39 return self.attrs[key]
40 return None
41
42 def getBinary(self):
43 return self.bin
44
45 def marshall(self):
46 d = json.dumps(self.attrs)
47 if self.bin:
48 d += ' \0\0 ' + self.bin
49 return d
50
51 @classmethod
52 def unmarshall(cls,d):
53 m = None
54 sep = d.find( ' \0\0 ' )
55 txt = None
56 bin = None
57 if sep == - 1 :
58 txt = d
59 else :
60 txt = d[:sep]
61 bin = d[sep + 2 :]
62 m = MessageBase()
63 try :
64 m.attrs = json.loads(txt)
65 if type(m.attrs) != type({}):
66 return None
67 m.bin = bin
68 except :
69 m = None
70 return m
71
72 class MsgCallReturn(MessageBase):
73 def __init__ (self,succ = True,errno = 0 ,errmsg = '' ,value = None,bin = None):
74 MessageBase. __init__ (self, ' callret ' ,bin)
75 self.attrs[ ' succ ' ] = succ
76 self.attrs[ ' errno ' ] = errno
77 self.attrs[ ' errmsg ' ] = errmsg
78 self.attrs[ ' value ' ] = value
79
80 class NetMetaPacket:
81 # [magic,size,compress,encrypt,version],[command text(json)],[\0\0],[binary data..]
82 def __init__ (self,msg = None,compress = COMPRESS_NONE,encrypt = ENCRYPT_NONE ):
83 self.msg = msg
84 self.size4 = 0
85 self.compress1 = compress
86 self.encrypt1 = encrypt
87 self.ver4 = 0x01000000 # means 1.0.0.0
88 magic4 = 0xEFD2BB99
89
90 @classmethod
91 def minSize(cls):
92 return 14
93
94 def marshall(self):
95 d = self.msg.marshall()
96 if self.compress1 == COMPRESS_ZLIB:
97 d = zlib.compress(d)
98 else :
99 self.compress1 = COMPRESS_NONE
100 self.encrypt1 = ENCRYPT_NONE
101 # [magic,size,compress,encrypt,version],[command text(json)],[\0\0],[binary data..]
102 r = struct.pack( ' !BBI ' ,self.compress1,self.encrypt1,self.ver4)
103 r += d
104 self.size4 = len(r) + 4
105 r = struct.pack( ' !II ' , self.magic4,self.size4) + r
106 # size =包含自身变量的整个包大小
107 return r
108
109
110
111 if __name__ == ' __main__ ' :
112
113 print NetMetaPacket(msg = MsgCallReturn(value = range( 10 ),bin = ' abc ' ),compress = COMPRESS_NONE).marshall()
114 print NetMetaPacket.minSize()
115
2
3 import socket,traceback,os,os.path,sys,time,struct,base64,gzip,array,json,zlib
4
5 '''
6 ------------------
7 msghdr
8 cmdtxt
9 \0\0
10 二进制流
11 -----------------
12 视频包由三部分构成: MetaMessage数据元封套,控制命令文本(json格式),二进制数据,后两者之间采用连续两个\0区分,表示开始二进制流数据
13 [metamsg,cmdtxt,bindata]
14 bindata部分格式、编码由cmdtxt控制
15
16 # [magic,size,compress,encrypt,version],[command text(json)],[\0\0],[binary data..]
17 '''
18
19 COMPRESS_NONE = 0
20 COMPRESS_ZLIB = 1
21 COMPRESS_BZIP2 = 2
22
23 ENCRYPT_NONE = 0
24 ENCRYPT_MD5 = 1
25 ENCRYPT_DES = 2
26
27
28 class MessageBase:
29 def __init__ (self,type = '' ,bin = None):
30 # self.type = type
31 self.attrs = { ' msg ' :type}
32 self.bin = bin
33
34 def getMsg(self):
35 return self.getValue( ' msg ' )
36
37 def getValue(self,key):
38 if self.attrs.has_key(key):
39 return self.attrs[key]
40 return None
41
42 def getBinary(self):
43 return self.bin
44
45 def marshall(self):
46 d = json.dumps(self.attrs)
47 if self.bin:
48 d += ' \0\0 ' + self.bin
49 return d
50
51 @classmethod
52 def unmarshall(cls,d):
53 m = None
54 sep = d.find( ' \0\0 ' )
55 txt = None
56 bin = None
57 if sep == - 1 :
58 txt = d
59 else :
60 txt = d[:sep]
61 bin = d[sep + 2 :]
62 m = MessageBase()
63 try :
64 m.attrs = json.loads(txt)
65 if type(m.attrs) != type({}):
66 return None
67 m.bin = bin
68 except :
69 m = None
70 return m
71
72 class MsgCallReturn(MessageBase):
73 def __init__ (self,succ = True,errno = 0 ,errmsg = '' ,value = None,bin = None):
74 MessageBase. __init__ (self, ' callret ' ,bin)
75 self.attrs[ ' succ ' ] = succ
76 self.attrs[ ' errno ' ] = errno
77 self.attrs[ ' errmsg ' ] = errmsg
78 self.attrs[ ' value ' ] = value
79
80 class NetMetaPacket:
81 # [magic,size,compress,encrypt,version],[command text(json)],[\0\0],[binary data..]
82 def __init__ (self,msg = None,compress = COMPRESS_NONE,encrypt = ENCRYPT_NONE ):
83 self.msg = msg
84 self.size4 = 0
85 self.compress1 = compress
86 self.encrypt1 = encrypt
87 self.ver4 = 0x01000000 # means 1.0.0.0
88 magic4 = 0xEFD2BB99
89
90 @classmethod
91 def minSize(cls):
92 return 14
93
94 def marshall(self):
95 d = self.msg.marshall()
96 if self.compress1 == COMPRESS_ZLIB:
97 d = zlib.compress(d)
98 else :
99 self.compress1 = COMPRESS_NONE
100 self.encrypt1 = ENCRYPT_NONE
101 # [magic,size,compress,encrypt,version],[command text(json)],[\0\0],[binary data..]
102 r = struct.pack( ' !BBI ' ,self.compress1,self.encrypt1,self.ver4)
103 r += d
104 self.size4 = len(r) + 4
105 r = struct.pack( ' !II ' , self.magic4,self.size4) + r
106 # size =包含自身变量的整个包大小
107 return r
108
109
110
111 if __name__ == ' __main__ ' :
112
113 print NetMetaPacket(msg = MsgCallReturn(value = range( 10 ),bin = ' abc ' ),compress = COMPRESS_NONE).marshall()
114 print NetMetaPacket.minSize()
115