最近做项目写了一个小 websocket 服务器但是有报错我自己没法搞定求大神解救
import socket
import time
import hashlib
import base64
import struct
import threading
import chardet
connlist = []
s = socket.socket()
host = "0.0.0.0"
port = 1999
s.bind((host, port))
s.listen(500)
def getheads(data):
data = data.decode()
datasplit = data.split("\r\n")
datasplit = datasplit[1:-2]
headslist = {}
for i in datasplit:
k,v = i.split(":",1)
headslist[k] = v.replace(' ','')
return headslist
def _get_data(info, setcode):
payload_len = info[1] & 127
fin = 1 if info[0] & 128 == 128 else 0
opcode = info[0] & 15
if payload_len == 126:
mask = info[4:8]
decoded = info[8:]
elif payload_len == 127:
mask = info[10:14]
decoded = info[14:]
else:
mask = info[2:6]
decoded = info[6:]
bytes_list = bytearray()
for i in range(len(decoded)):
chunk = decoded[i] ^ mask[i % 4]
bytes_list.append(chunk)
if opcode == 0x00:
opcode = setcode
if opcode == 0x01:
body = str(bytes_list, encoding='utf-8',errors='ignore')
return fin, opcode, body
else:
body = decoded
return fin, opcode, body
def recv(conn):
msg = ''
opcode = 0x00
while True:
raw_data = b''
while True:
section = conn.recv(1024)
raw_data += section
if len(section) < 1024:
break
fin, _opcode, fragment = _get_data(raw_data,opcode)
opcode = _opcode if _opcode != 0x00 else opcode
msg += fragment
if fin == 1:
break
return msg
def send(conn,msg,fin=True):
data = struct.pack('B', 129) if fin else struct.pack('B', 0)
msg_len = len(msg)
if msg_len <= 125:
data += struct.pack('B', msg_len)
elif msg_len <= (2**16 - 1):
data += struct.pack('!BH', 126, msg_len)
elif msg_len <= (2**64 - 1):
data += struct.pack('!BQ', 127, msg_len)
else:
while True:
fragment = msg[:(2**64 - 1)]
msg -= fragment
if msg > (2**64 - 1):
conn.send(fragment, False)
else:
conn.send(fragment)
data += bytes(msg,encoding='utf-8',errors='ignore')
conn.send(data)
def shakehands(conn):
data = conn.recv(1024)
heads = getheads(data)
msg = heads["Sec-WebSocket-Key"]
key = msg + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
ser_key = hashlib.sha1(key.encode('utf-8')).digest()
token = base64.b64encode(ser_key)
message = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "+bytes.decode(token)+"\r\nWebSocket-Origin: "+str(heads["Origin"])+"\r\nWebSocket-Location: ws://"+str(heads["Host"])+"\r\n\r\n"
conn.send(message.encode())
connlist.append(conn)
def websockethandle(conn,addr):
shakehands(conn)
ip,port = addr
print(ip+" 连入")
print("当前用户数:"+str(len(connlist)))
while True:
try:
data= recv(conn)
except Exception as e:
print(e)
print(ip+" 断开")
conn.close()
connlist.remove(conn)
print("当前用户数:"+str(len(connlist)))
break
for i in connlist:
if i != conn:
send(i,data)
while True:
conn,addr = s.accept()
threading.Thread(target=websockethandle,args=(conn,addr,)).start()
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.