windowsPython2.79,chrome37firefox35通过
代码是在别人(cddn有人提问)基础上改的,主要改动了parsedata和sendmessage这2个函数.
改代码参考下面了这段文档.主要是第5条,发送的数据长度分别是8bit和16bit和64bit(即127,65535,和2^64-1)三种情况 发送和收取是一样的,例如
1.长度小于125时(由于使用126,127用作标志位.)
2.数据长度在128-65525之间时,PayloadLength位设为126,后面额外使用16bit表示长度(前面的126不再是长度的一部分)
3.数据长度在65526-2^64-1之间时,PayloadLength位设为127,后面额外使用64bit表示长度(前面的127不再是长度的一部分)
1. Fin(bit0):determinesifthisisthelastframeinthemessage.Thiswouldbesetto1ontheendofaseriesofframes,orinasingle-framemessage,itwouldbesetto1asitisboththefirstandlastframe.
2. RSV1,RSV2,RSV3(bits1-3):thesethreebitsarereservedforwebsocketextensions,andshouldbe0unlessaspecificextensionrequirestheuseofanyofthesebytes. 3. Opcode(bits4-7):thesefourbitsdeteriminethetypeoftheframe.ControlframescommunicateWebSocketstate,whilenon-controlframescommunicatedata.Thevarioustypesofcodesinclude: 1. x0:continuationframe;thisframecontainsdatathatshouldbeappendedtothepreviousframe 2. x1:textframe;thisframe(andanyfollowing)containstext
3. x2:binaryframe;thisframe(andanyfollowing)containsbinarydata
4. x3-x7:non-controlreservedframes;thesearereservedforpossiblewebsocketextensions
5. x8:closeframe;thisframeshouldendtheconnection 6. x9:pingframe 7. xA:pongframe
8. xB-xF:controlreservedframes
4. Mask(bit8):thisbitdetermineswhetherthisspecificframeusesamaskornot. 5. PayloadLength(bits9-15,or16-31,or16-79):thesesevenbytesdeterminethepayloadlength.Ifthelengthis126,thelengthisactuallydeterminedbybits16through31(thatis,thefollowingtwobytes).Ifthelengthis127,thelengthisactuallydeterminedbybits16through79(thatis,thefollowingeightbytes).
6. MaskingKey(thefollowingfourbytes):thisrepresentsthemask,iftheMaskbitissetto1.
7. PayloadData(thefollowingdata):finally,thedata.Thepayloaddatamaybesentovermultipleframes;weknowthesizeoftheentiremessagebythepayloadlengththatwassent,andcanappenddatatogethertoformasinglemessageuntilwereceivethemessagewiththeFinflag.Eachconsecutivepayload,ifitexists,willcontainthe0“continuationframe”opcode.
服务器
[python]viewplaincopy
1. #coding=utf8 2. #!/usr/bin/python 3. 4.
5. importstruct,socket 6. importhashlib
7. importthreading,random 8. importtime 9. importstruct
10. frombase64importb64encode,b64decode 11. 12.
13. connectionlist={} 14. g_code_length=0 15. g_header_length=0 16. 17.
18. defhex2dec(string_num):
19. returnstr(int(string_num.upper(),16)) 20.
21. 22. 23.
24. defget_datalength(msg): 25. globalg_code_length 26. globalg_header_length 27.
28. print(len(msg))
29. g_code_length=ord(msg[1])&127 30. received_length=0; 31. ifg_code_length==126: 32. #g_code_length=msg[2:4]
33. #g_code_length=(ord(msg[2])<<8)+(ord(msg[3])) 34. g_code_length=struct.unpack('>H',str(msg[2:4]))[0] 35. g_header_length=8 36. elifg_code_length==127: 37. #g_code_length=msg[2:10]
38. g_code_length=struct.unpack('>Q',str(msg[2:10]))[0] 39. g_header_length=14 40. else:
41. g_header_length=6
42. g_code_length=int(g_code_length) 43. returng_code_length 44.
45. defparse_data(msg): 46. globalg_code_length
47. g_code_length=ord(msg[1])&127 48. received_length=0; 49. ifg_code_length==126:
50. g_code_length=struct.unpack('>H',str(msg[2:4]))[0] 51. masks=msg[4:8] 52. data=msg[8:]
53. elifg_code_length==127:
54. g_code_length=struct.unpack('>Q',str(msg[2:10]))[0] 55. masks=msg[10:14] 56. data=msg[14:] 57. else:
58. masks=msg[2:6] 59. data=msg[6:] 60. 61. 62. i=0 63. raw_str='' 64.
65.
66. fordindata:
67. raw_str+=chr(ord(d)^ord(masks[i%4])) 68. i+=1 69. 70.
71. print(u\"总长度是:%d\"%int(g_code_length)) 72. returnraw_str 73. 74.
75. defsendMessage(message): 76. globalconnectionlist 77.
78. message_utf_8=message.encode('utf-8') 79. forconnectioninconnectionlist.values(): 80. back_str=[]
81. back_str.append('\\x81') 82. data_length=len(message_utf_8) 83. 84.
85. ifdata_length<=125:
86. back_str.append(chr(data_length)) 87. elifdata_length<=65535:
88. back_str.append(struct.pack('b',126))
89. back_str.append(struct.pack('>h',data_length)) 90. #back_str.append(chr(data_length>>8)) 91. #back_str.append(chr(data_length&0xFF)) 92. #a=struct.pack('>h',data_length) 93. #b=chr(data_length>>8) 94. #c=chr(data_length&0xFF) 95. elifdata_length<=(2^64-1): 96. #back_str.append(chr(127))
97. back_str.append(struct.pack('b',127))
98. back_str.append(struct.pack('>q',data_length)) 99. #back_str.append(chr(data_length>>8)) 100. #back_str.append(chr(data_length&0xFF)) 101. else:
102. print(u'太长了') 103. msg=''
104. forcinback_str: 105. msg+=c;
106. back_str=str(msg)+message_utf_8#.encode('utf-8')
107. #connection.send(str.encode(str(u\"\\x00%s\\xFF\\n\\n\"%message)))#这个是旧版 108. #print(u'sendmessage:'+message)
109. ifback_str!=Noneandlen(back_str)>0: 110. print(back_str)
111. connection.send(back_str) 112. 113.
114. defdeleteconnection(item): 115. globalconnectionlist
116. delconnectionlist['connection'+item] 117. 118.
119. classWebSocket(threading.Thread):#继承Thread 120. 121.
122. GUID=\"258EAFA5-E914-47DA-95CA-C5AB0DC85B11\" 123. 124.
125. def__init__(self,conn,index,name,remote,path=\"/\"): 126. threading.Thread.__init__(self)#初始化父类Thread 127. self.conn=conn 128. self.index=index 129. self.name=name 130. self.remote=remote 131. self.path=path 132. self.buffer=\"\" 133. self.buffer_utf8=\"\" 134. self.length_buffer=0
135. defrun(self):#重载Thread的run 136. print('Socket%sStart!'%self.index) 137. headers={}
138. self.handshaken=False 139. 140.
141. whileTrue:
142. ifself.handshaken==False:
143. print('Socket%sStartHandshakenwith%s!'%(self.index,self.remote)) 144. self.buffer+=bytes.decode(self.conn.recv(1024)) 145. 146.
147. ifself.buffer.find('\\r\\n\\r\\n')!=-1:
148. header,data=self.buffer.split('\\r\\n\\r\\n',1) 149. forlineinheader.split(\"\\r\\n\")[1:]: 150. key,value=line.split(\":\",1) 151. headers[key]=value 152.
153.
154. headers[\"Location\"]=(\"ws://%s%s\"%(headers[\"Host\"],self.path)) 155. key=headers['Sec-WebSocket-Key']
156. token=b64encode(hashlib.sha1(str.encode(str(key+self.GUID))).digest()) 157. 158.
159. handshake=\"HTTP/1.1101SwitchingProtocols\\r\\n\"\\ 160. \"Upgrade:websocket\\r\\n\"\\ 161. \"Connection:Upgrade\\r\\n\"\\
162. \"Sec-WebSocket-Accept:\"+bytes.decode(token)+\"\\r\\n\"\\ 163. \"WebSocket-Origin:\"+str(headers[\"Origin\"])+\"\\r\\n\"\\ 164. \"WebSocket-Location:\"+str(headers[\"Location\"])+\"\\r\\n\\r\\n\" 165. 166.
167. self.conn.send(str.encode(str(handshake))) 168. self.handshaken=True
169. print('Socket%sHandshakenwith%ssuccess!'%(self.index,self.remote)) 170. sendMessage(u'Welcome,'+self.name+'!') 171. self.buffer_utf8=\"\" 172. g_code_length=0 173. 174. 175. else:
176. globalg_code_length 177. globalg_header_length 178. mm=self.conn.recv(128) 179. iflen(mm)<=0: 180. continue
181. ifg_code_length==0: 182. get_datalength(mm) 183. #接受的长度
184. self.length_buffer=self.length_buffer+len(mm) 185. self.buffer=self.buffer+mm
186. ifself.length_buffer-g_header_length 190. msg_unicode=str(self.buffer_utf8).decode('utf-8','ignore')#unicode 191. ifmsg_unicode=='quit': 192. print(u'Socket%sLogout!'%(self.index)) 193. nowTime=time.strftime('%H:%M:%S',time.localtime(time.time())) 194. sendMessage(u'%s%ssay:%s'%(nowTime,self.remote,self.name+'Logout')) 195. deleteconnection(str(self.index)) 196. self.conn.close() 197. break#退出线程 198. else: 199. #print(u'Socket%sGotmsg:%sfrom%s!'%(self.index,msg_unicode,self.remote)) 200. nowTime=time.strftime(u'%H:%M:%S',time.localtime(time.time())) 201. sendMessage(u'%s%ssay:%s'%(nowTime,self.remote,msg_unicode)) 202. #重置buffer和bufferlength 203. self.buffer_utf8=\"\" 204. self.buffer=\"\" 205. g_code_length=0 206. self.length_buffer=0 207. self.buffer=\"\" 208. 209. 210. classWebSocketServer(object): 211. def__init__(self): 212. self.socket=None 213. defbegin(self): 214. print('WebSocketServerStart!') 215. self.socket=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 216. self.socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 217. self.socket.bind((\"127.0.0.1\",12345)) 218. self.socket.listen(50) 219. 220. 221. globalconnectionlist 222. 223. 224. i=0 225. whileTrue: 226. connection,address=self.socket.accept() 227. 228. 229. username=address[0] 230. newSocket=WebSocket(connection,i,username,address) 231. newSocket.start()#开始线程,执行run函数 232. connectionlist['connection'+str(i)]=connection 233. i=i+1 234. 235. 236. if__name__==\"__main__\": 237. server=WebSocketServer() 238. server.begin() 客户端 测试了chrome37,firefox35 [html]viewplaincopy 1. 2. 3. 4. 23. 87. 88. 89. 90. 91. 95. WebSocket
93.
94.
96. 100.