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