用python实现的websocket代码.docx
《用python实现的websocket代码.docx》由会员分享,可在线阅读,更多相关《用python实现的websocket代码.docx(13页珍藏版)》请在冰豆网上搜索。
![用python实现的websocket代码.docx](https://file1.bdocx.com/fileroot1/2023-1/27/b0278a88-5aa6-4ce3-a66f-85e7eea62726/b0278a88-5aa6-4ce3-a66f-85e7eea627261.gif)
用python实现的websocket代码
用python实现的websocket代码
ubuntu下python2.76
windows Python 2.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] viewplain copy
1.#coding=utf8
2.#!
/usr/bin/python
3.
4.
5.import struct,socket
6.import hashlib
7.import threading,random
8.import time
9.import struct
10.from base64 import b64encode, b64decode
11.
12.
13.connectionlist = {}
14.g_code_length = 0
15.g_header_length = 0
16.
17.
18.def hex2dec(string_num):
19. return str(int(string_num.upper(), 16))
20.
21.
22.
23.
24.def get_datalength(msg):
25. global g_code_length
26. global g_header_length
27.
28. print (len(msg))
29. g_code_length = ord(msg[1]) & 127
30. received_length = 0;
31. if g_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. elif g_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. return g_code_length
44.
45.def parse_data(msg):
46. global g_code_length
47. g_code_length = ord(msg[1]) & 127
48. received_length = 0;
49. if g_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. elif g_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. for d in data:
67. raw_str += chr(ord(d) ^ ord(masks[i%4]))
68. i += 1
69.
70.
71. print (u"总长度是:
%d" % int(g_code_length))
72. return raw_str
73.
74.
75.def sendMessage(message):
76. global connectionlist
77.
78. message_utf_8 = message.encode('utf-8')
79. for connection in connectionlist.values():
80. back_str = []
81. back_str.append('\x81')
82. data_length = len(message_utf_8)
83.
84.
85. if data_length <= 125:
86. back_str.append(chr(data_length))
87. elif data_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. elif data_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. for c in back_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'send message:
' + message)
109. if back_str !
= None and len(back_str) > 0:
110. print (back_str)
111. connection.send(back_str)
112.
113.
114.def deleteconnection(item):
115. global connectionlist
116. del connectionlist['connection'+item]
117.
118.
119.class WebSocket(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. def run(self):
#重载Thread的run
136. print('Socket%s Start!
' % self.index)
137. headers = {}
138. self.handshaken = False
139.
140.
141. while True:
142. if self.handshaken == False:
143. print ('Socket%s Start Handshaken with %s!
' % (self.index,self.remote))
144. self.buffer += bytes.decode(self.conn.recv(1024))
145.
146.
147. if self.buffer.find('\r\n\r\n') !
= -1:
148. header, data = self.buffer.split('\r\n\r\n', 1)
149. for line in header.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.1 101 Switching Protocols\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 %s Handshaken with %s success!
' %(self.index, self.remote))
170. sendMessage(u'Welcome, ' + self.name + ' !
')
171. self.buffer_utf8 = ""
172. g_code_length = 0
173.
174.
175. else:
176. global g_code_length
177. global g_header_length
178. mm=self.conn.recv(128)
179. if len(mm) <= 0:
180. continue
181. if g_code_length == 0:
182. get_datalength(mm)
183. #接受的长度
184. self.length_buffer = self.length_buffer + len(mm)
185. self.buffer = self.buffer + mm
186. if self.length_buffer - g_header_length < g_code_length :
187. continue
188. else :
189. self.buffer_utf8 = parse_data(self.buffer) #utf8
190. msg_unicode = str(self.buffer_utf8).decode('utf-8', 'ignore') #unicode
191. if msg_unicode=='quit':
192. print (u'Socket%s Logout!
' % (self.index))
193. nowTime = time.strftime('%H:
%M:
%S',time.localtime(time.time()))
194. se