您的当前位置:首页正文

websocket编程

来源:画鸵萌宠网
ubuntu下python2.76

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_length189. self.buffer_utf8=parse_data(self.buffer)#utf8

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. WebSocket 5. 6. 22.

23. 87. 88. 89. 90.

91. 92.

WebSocket

93.

94.

95.

96. 97. 发送 98. 99.

100.

因篇幅问题不能全部显示,请点此查看更多更全内容

Top