用python实现的websocket代码.docx
《用python实现的websocket代码.docx》由会员分享,可在线阅读,更多相关《用python实现的websocket代码.docx(15页珍藏版)》请在冰点文库上搜索。
用python实现的websocket代码
用python实现的websocket代码
ubuntu下
windows ,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再也不是长度的一部份)
Fin(bit0):
determinesifthisisthelastframeinthemessage.Thiswouldbesetto1ontheendofaseriesofframes,orinasingle-framemessage,itwouldbesetto1asitisboththefirstandlastframe.
RSV1,RSV2,RSV3(bits1-3):
thesethreebitsarereservedforwebsocketextensions,andshouldbe0unlessaspecificextensionrequirestheuseofanyofthesebytes.
Opcode(bits4-7):
thesefourbitsdeteriminethetypeoftheframe.ControlframescommunicateWebSocketstate,whilenon-controlframescommunicatedata.Thevarioustypesofcodesinclude:
x0:
continuationframe;thisframecontainsdatathatshouldbeappendedtothepreviousframe
x1:
textframe;thisframe(andanyfollowing)containstext
x2:
binaryframe;thisframe(andanyfollowing)containsbinarydata
x3-x7:
non-controlreservedframes;thesearereservedforpossiblewebsocketextensions
x8:
closeframe;thisframeshouldendtheconnection
x9:
pingframe
xA:
pongframe
xB-xF:
controlreservedframes
Mask(bit8):
thisbitdetermineswhetherthisspecificframeusesamaskornot.
PayloadLength(bits9-15,or16-31,or16-79):
thesesevenbytesdeterminethepayloadlength.Ifthelengthis126,thelengthisactuallydeterminedbybits16through31(thatis,thefollowingtwobytes).Ifthelengthis127,thelengthisactuallydeterminedbybits16through79(thatis,thefollowingeightbytes).
MaskingKey(thefollowingfourbytes):
thisrepresentsthemask,iftheMaskbitissetto1.
PayloadData(thefollowingdata):
finally,thedata.Thepayloaddatamaybesentovermultipleframes;weknowthesizeoftheentiremessagebythepayloadlengththatwassent,andcanappenddatatogethertoformasinglemessageuntilwereceivethemessagewiththeFinflag.Eachconsecutivepayload,ifitexists,willcontainthe0“continuationframe”opcode.
服务端代码:
#coding=utf8
#!
/usr/bin/python
import struct,socket
import hashlib
import threading,random
import time
import struct
from base64 import b64encode, b64decode
connectionlist = {}
g_code_length = 0
g_header_length = 0
def hex2dec(string_num):
return str(int(), 16))
def get_datalength(msg):
global g_code_length
global g_header_length
print (len(msg))
g_code_length = ord(msg[1]) & 127
received_length = 0;
if g_code_length == 126:
#g_code_length = msg[2:
4]
#g_code_length = (ord(msg[2])<<8) + (ord(msg[3]))
g_code_length = ('>H', str(msg[2:
4]))[0]
g_header_length = 8
elif g_code_length == 127:
#g_code_length = msg[2:
10]
g_code_length = ('>Q', str(msg[2:
10]))[0]
g_header_length = 14
else:
g_header_length = 6
g_code_length = int(g_code_length)
return g_code_length
def parse_data(msg):
global g_code_length
g_code_length = ord(msg[1]) & 127
received_length = 0;
if g_code_length == 126:
g_code_length = ('>H', str(msg[2:
4]))[0]
masks = msg[4:
8]
data = msg[8:
]
elif g_code_length == 127:
g_code_length = ('>Q', str(msg[2:
10]))[0]
masks = msg[10:
14]
data = msg[14:
]
else:
masks = msg[2:
6]
data = msg[6:
]
i = 0
raw_str = ''
for d in data:
raw_str += chr(ord(d) ^ ord(masks[i%4]))
i += 1
print (u"总长度是:
%d" % int(g_code_length))
return raw_str
def sendMessage(message):
global connectionlist
message_utf_8 = ('utf-8')
for connection in ():
back_str = []
('\x81')
data_length = len(message_utf_8)
if data_length <= 125:
(chr(data_length))
elif data_length <= 65535 :
('b', 126))
('>h', data_length))
#(chr(data_length >> 8))
#(chr(data_length & 0xFF))
#a = ('>h', data_length)
#b = chr(data_length >> 8)
#c = chr(data_length & 0xFF)
elif data_length <= (2^64-1):
#(chr(127))
('b', 127))
('>q', data_length))
#(chr(data_length >> 8))
#(chr(data_length & 0xFF))
else :
print (u'太长了')
msg = ''
for c in back_str:
msg += c;
back_str = str(msg) + message_utf_8#.encode('utf-8')
#(str(u"\x00%s\xFF\n\n" % message))) #这个是旧版
#print (u'send message:
' + message)
if back_str !
= None and len(back_str) > 0:
print (back_str)
(back_str)
def deleteconnection(item):
global connectionlist
del connectionlist['connection'+item]
class WebSocket:
#继承Thread
GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
def __init__(self,conn,index,name,remote, path="/"):
初始化父类Thread
= conn
= index
= name
= remote
= path
= ""
= ""
= 0
def run(self):
#重载Thread的run
print('Socket%s Start!
' %
headers = {}
= False
while True:
if == False:
print ('Socket%s Start Handshaken with %s!
' % ,)
+=
if '\r\n\r\n') !
= -1:
header, data = '\r\n\r\n', 1)
for line in ("\r\n")[1:
]:
key, value = (":
", 1)
headers[key] = value
headers["Location"] = ("" %(headers["Host"], )
key = headers['Sec-WebSocket-Key']
token = b64encode(str(key + )).digest())
handshake="HTTP/ 101 Switching Protocols\r\n"\
"Upgrade:
websocket\r\n"\
"Connection:
Upgrade\r\n"\
"Sec-WebSocket-Accept:
"+(token)+"\r\n"\
"WebSocket-Origin:
"+str(headers["Origin"])+"\r\n"\
"WebSocket-Location:
"+str(headers["Location"])+"\r\n\r\n"
= True
print ('Socket %s Handshaken with %s success!
' %, )
sendMessage(u'Welcome, ' + + ' !
')
= ""
g_code_length = 0
else:
global g_code_length
global g_header_length
mm=
if len(mm) <= 0:
continue
if g_code_length == 0:
get_datalength(mm)
#接受的长度
= + len(mm)
= + mm
if - g_header_length < g_code_length :
continue
else :
= parse_data #utf8
msg_unicode = str.decode('utf-8', 'ignore') #unicode
if msg_unicode=='quit':
print (u'Socket%s Logout!
' % )
nowTime = ('%H:
%M:
%S',()))
sendMessage(u'%s %s say:
%s' % (nowTime, , +' Logout'))
deleteconnection(str)
break #退出线程
else:
#print (u'Socket%s Got msg:
%s from %s!
' % , msg_unicode, )
nowTime = (u'%H:
%M:
%S',()))
sendMessage(u'%s %s say:
%s' % (nowTime, , msg_unicode))
#重置buffer和bufferlength
= ""
= ""
g_code_length = 0
= 0
= ""
class WebSocketServer(object):
def __init__(self):
= None
def begin(self):
print( 'WebSocketServer Start!
')
= ,
"",12345))
global connectionlist
i=0
while True:
connection, address =
username=address[0]
newSocket = WebSocket(connection,i,username,address)
() #开始线程,执行run函数
connectionlist['connection'+str(i)]=connection
i = i + 1
if __name__ == "__main__":
server = WebSocketServer()
()
客户端代码:
DOCTYPE html>
1.
WebSocket