我写了一个简单的WebSocket客户端。我使用了在SO上找到的代码,链接如下:如何在服务器端发送和接收WebSocket消息?。
我使用的是Python 2.7,并且我的服务器是echo.websocket.org,使用TCP 80端口。基本上,我认为我在接收消息时存在问题。(或者发送也有问题?)
至少我确定握手阶段没有问题,因为我收到了良好的握手响应:
这里有什么问题?握手后变得复杂起来。
我不想使用库(我知道如何使用它们)。问题是在没有使用库的情况下,只使用套接字实现相同的功能。
我只想向
对于下面的测试,我使用了我的浏览器:
未屏蔽的数据,从服务器到客户端: 屏蔽的数据,从客户端到服务器:
我使用的是Python 2.7,并且我的服务器是echo.websocket.org,使用TCP 80端口。基本上,我认为我在接收消息时存在问题。(或者发送也有问题?)
至少我确定握手阶段没有问题,因为我收到了良好的握手响应:
HTTP/1.1 101 Web Socket Protocol Handshake
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: content-type
Access-Control-Allow-Headers: authorization
Access-Control-Allow-Headers: x-websocket-extensions
Access-Control-Allow-Headers: x-websocket-version
Access-Control-Allow-Headers: x-websocket-protocol
Access-Control-Allow-Origin: http://example.com
Connection: Upgrade
Date: Tue, 02 May 2017 21:54:31 GMT
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Server: Kaazing Gateway
Upgrade: websocket
我的代码:
#!/usr/bin/env python
import socket
def encode_text_msg_websocket(data):
bytesFormatted = []
bytesFormatted.append(129)
bytesRaw = data.encode()
bytesLength = len(bytesRaw)
if bytesLength <= 125:
bytesFormatted.append(bytesLength)
elif 126 <= bytesLength <= 65535:
bytesFormatted.append(126)
bytesFormatted.append((bytesLength >> 8) & 255)
bytesFormatted.append(bytesLength & 255)
else:
bytesFormatted.append(127)
bytesFormatted.append((bytesLength >> 56) & 255)
bytesFormatted.append((bytesLength >> 48) & 255)
bytesFormatted.append((bytesLength >> 40) & 255)
bytesFormatted.append((bytesLength >> 32) & 255)
bytesFormatted.append((bytesLength >> 24) & 255)
bytesFormatted.append((bytesLength >> 16) & 255)
bytesFormatted.append((bytesLength >> 8) & 255)
bytesFormatted.append(bytesLength & 255)
bytesFormatted = bytes(bytesFormatted)
bytesFormatted = bytesFormatted + bytesRaw
return bytesFormatted
def dencode_text_msg_websocket(stringStreamIn):
byteArray = [ord(character) for character in stringStreamIn]
datalength = byteArray[1] & 127
indexFirstMask = 2
if datalength == 126:
indexFirstMask = 4
elif datalength == 127:
indexFirstMask = 10
masks = [m for m in byteArray[indexFirstMask: indexFirstMask + 4]]
indexFirstDataByte = indexFirstMask + 4
decodedChars = []
i = indexFirstDataByte
j = 0
while i < len(byteArray):
decodedChars.append(chr(byteArray[i] ^ masks[j % 4]))
i += 1
j += 1
return ''.join(decodedChars)
# connect
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((socket.gethostbyname('echo.websocket.org'), 80))
# handshake
handshake = 'GET / HTTP/1.1\r\nHost: echo.websocket.org\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Key: gfhjgfhjfj\r\nOrigin: http://example.com\r\nSec-WebSocket-Protocol: echo\r\n' \
'Sec-WebSocket-Version: 13\r\n\r\n'
sock.send(handshake)
print sock.recv(1024)
# send test msg
msg = encode_text_msg_websocket('hello world!')
sock.sendall(msg)
# receive it back
response = dencode_text_msg_websocket(sock.recv(1024))
print '--%s--' % response
sock.close()
这里有什么问题?握手后变得复杂起来。
dencode_text_msg_websocket
方法返回一个空字符串,但它应该返回我发送到服务器的相同字符串,即 hello world!
。我不想使用库(我知道如何使用它们)。问题是在没有使用库的情况下,只使用套接字实现相同的功能。
我只想向
echo.websocket.org 服务器
发送一条消息并接收响应。我不想修改标头,只需构建与此服务器使用的标头相同的标头。我使用 Wireshark 检查了它们的外观,并尝试使用 Python 构建相同的数据包。对于下面的测试,我使用了我的浏览器:
未屏蔽的数据,从服务器到客户端: 屏蔽的数据,从客户端到服务器:
echo.websocket.org
服务器发送一条消息,仅此而已。我不想修改头文件,只是构建与该服务器使用的相同头文件。我使用Wireshark检查了它们应该看起来像什么,并尝试使用Python构建相同的数据包。请查看我的编辑。 - yakbyteArray = stringStreamIn
转换,而是仅依赖于转换单个字符来获取长度。原始代码将整个输入字符串转换为byteArray = [ord(character) for character in stringStreamIn]
。 - Rolf of Saxonyprint
输出一个空字符串作为响应。 - yakwebsocket-client
中的Python代码。可以使用命令sudo pip install websocket-client
安装该库。 - Rolf of Saxony