当服务器在打开握手后向客户端发送消息时,为什么我得到无效的帧头?
Why am I getting invalid frame header, when the server sends a message to the client after the opening handshake?
我正在尝试在 python 中制作一个基本的 websocket 服务器,在打开握手后,客户端发送一条消息,在服务器取消屏蔽后,它应该发送一条消息,从我浏览器的开发人员工具的网络选项卡,我可以看到客户端已发送消息,并且从我服务器的控制台我可以看到已被取消屏蔽的消息。问题是,我似乎无法向客户端发送消息。
在下面的代码中,我尝试发送单帧未屏蔽文本消息,如 websocket protocol's documentation 的示例所示,但我从浏览器的控制台收到错误消息,在服务器之后已发送消息:
这是我的代码:
import socket
import threading
import hashlib
from time import sleep
from base64 import encodebytes
bind_ip = '127.0.0.1'
bind_port = 8000
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
print('Listening on {}:{}'.format(bind_ip, bind_port))
def decodeMessage(bytesArr):
if (bytesArr[0] & 0xF == 0x1):
unmasked = bytearray(b"\x00"*len(bytesArr))
for i in range(6, len(bytesArr)):
j = ((i-6) % 4)
unmasked[i] = bytesArr[i] ^ bytesArr[2+j]
return unmasked[6:]
def handle_client_connection(client_socket):
request = client_socket.recv(1024)
headers = request.split(b"\r\n")
key = b""
for header in headers:
if (header.find(b"Sec-WebSocket-Key:") != -1):
key = header[19:]
key = encodebytes(hashlib.sha1(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".encode()).digest())
client_socket.send(b"""HTTP/1.1 101 Switching Protocols
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: %s
""" % key)
sleep(1)
msg = decodeMessage(client_socket.recv(1024))
print(msg)
client_socket.send(b"\x81\x05Hello") # sending the encapsulated message
while KeyboardInterrupt:
client_sock, address = server.accept()
print('Accepted connection from {}:{}'.format(address[0], address[1]))
client_handler = threading.Thread(target = handle_client_connection, args = (client_sock,))
client_handler.start()
那么,我做错了什么,我该如何解决?
提前致谢!
我发现问题出在 encodebytes
函数上,因为它在 base64 编码密钥的末尾放置了一个换行符,这可以通过将 encodebytes
更改为 b64encode
,其工作方式相同。
我正在尝试在 python 中制作一个基本的 websocket 服务器,在打开握手后,客户端发送一条消息,在服务器取消屏蔽后,它应该发送一条消息,从我浏览器的开发人员工具的网络选项卡,我可以看到客户端已发送消息,并且从我服务器的控制台我可以看到已被取消屏蔽的消息。问题是,我似乎无法向客户端发送消息。
在下面的代码中,我尝试发送单帧未屏蔽文本消息,如 websocket protocol's documentation 的示例所示,但我从浏览器的控制台收到错误消息,在服务器之后已发送消息:
这是我的代码:
import socket
import threading
import hashlib
from time import sleep
from base64 import encodebytes
bind_ip = '127.0.0.1'
bind_port = 8000
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((bind_ip, bind_port))
server.listen(5)
print('Listening on {}:{}'.format(bind_ip, bind_port))
def decodeMessage(bytesArr):
if (bytesArr[0] & 0xF == 0x1):
unmasked = bytearray(b"\x00"*len(bytesArr))
for i in range(6, len(bytesArr)):
j = ((i-6) % 4)
unmasked[i] = bytesArr[i] ^ bytesArr[2+j]
return unmasked[6:]
def handle_client_connection(client_socket):
request = client_socket.recv(1024)
headers = request.split(b"\r\n")
key = b""
for header in headers:
if (header.find(b"Sec-WebSocket-Key:") != -1):
key = header[19:]
key = encodebytes(hashlib.sha1(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11".encode()).digest())
client_socket.send(b"""HTTP/1.1 101 Switching Protocols
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: %s
""" % key)
sleep(1)
msg = decodeMessage(client_socket.recv(1024))
print(msg)
client_socket.send(b"\x81\x05Hello") # sending the encapsulated message
while KeyboardInterrupt:
client_sock, address = server.accept()
print('Accepted connection from {}:{}'.format(address[0], address[1]))
client_handler = threading.Thread(target = handle_client_connection, args = (client_sock,))
client_handler.start()
那么,我做错了什么,我该如何解决? 提前致谢!
我发现问题出在 encodebytes
函数上,因为它在 base64 编码密钥的末尾放置了一个换行符,这可以通过将 encodebytes
更改为 b64encode
,其工作方式相同。