gpt4 book ai didi

python - 通过 Python 套接字/WebSocket 客户端发送/接收 WebSocket 消息

转载 作者:太空狗 更新时间:2023-10-30 00:13:07 25 4
gpt4 key购买 nike

我写了一个简单的 WebSocket 客户端。我在这里使用了我在 SO 上找到的代码:How can I send and receive WebSocket messages on the server side? .

我正在使用 Python 2.7,我的服务器是 echo.websocket.org,在 80 TCP 端口上。基本上,我认为我在接收消息方面有问题。 (或者发送也有误?)

至少我确定握手一切正常,因为我收到了良好的握手响应:

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 服务器 发送消息并接收响应,仅此而已。我不想修改 header ,只是像该服务器使用的那样构建 header 。我使用 Wireshark 检查了它们的外观,并尝试使用 Python 构建相同的数据包。

对于下面的测试,我使用了我的浏览器:

未屏蔽的数据,从服务器到客户端:

enter image description here

屏蔽数据,从客户端到服务器:

enter image description here

最佳答案

我已经将您的代码修改为至少可以发送回复和接收回复的内容,方法是更改​​编码以使用 chr() 将字节字符串而不是小数插入到 header 中。我单独留下了解码,但这里的另一个答案有一个解决方案。
这里详细介绍了真正的胆量https://www.rfc-editor.org/rfc/rfc6455.txt
其中详细说明了您必须做什么

#!/usr/bin/env python
import socket
def encode_text_msg_websocket(data):
bytesFormatted = []
bytesFormatted.append(chr(129))
bytesRaw = data.encode()
bytesLength = len(bytesRaw)
if bytesLength <= 125:
bytesFormatted.append(chr(bytesLength))
elif 126 <= bytesLength <= 65535:
bytesFormatted.append(chr(126))
bytesFormatted.append((chr(bytesLength >> 8)) & 255)
bytesFormatted.append(chr(bytesLength) & 255)
else:
bytesFormatted.append(chr(127))
bytesFormatted.append(chr((bytesLength >> 56)) & 255)
bytesFormatted.append(chr((bytesLength >> 48)) & 255)
bytesFormatted.append(chr((bytesLength >> 40)) & 255)
bytesFormatted.append(chr((bytesLength >> 32)) & 255)
bytesFormatted.append(chr((bytesLength >> 24)) & 255)
bytesFormatted.append(chr((bytesLength >> 16)) & 255)
bytesFormatted.append(chr((bytesLength >> 8)) & 255)
bytesFormatted.append(chr(bytesLength) & 255)
send_str = ""
for i in bytesFormatted:
send_str+=i
send_str += bytesRaw
return send_str

# connect
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5.0)
try:
sock.connect((socket.gethostbyname('ws.websocket.org'), 80))
except:
print "Connection failed"
handshake = '\
GET /echo HTTP/1.1\r\n\
Host: echo.websocket.org\r\n\
Upgrade: websocket\r\n\
Connection: Upgrade\r\n\
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n\
Origin: http://example.com\r\n\
WebSocket-Protocol: echo\r\n\
Sec-WebSocket-Version: 13\r\n\r\n\
'
sock.send(bytes(handshake))
data = sock.recv(1024).decode('UTF-8')
print data

# send test msg
msg = encode_text_msg_websocket('Now is the winter of our discontent, made glorious Summer by this son of York')
print "Sent: ",repr(msg)
sock.sendall(bytes(msg))
# receive it back
response = sock.recv(1024)
#decode not sorted so ignore the first 2 bytes
print "\nReceived: ", response[2:].decode()
sock.close()

结果:

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: Mon, 08 May 2017 15:08:33 GMT
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Server: Kaazing Gateway
Upgrade: websocket


Sent: '\x81MNow is the winter of our discontent, made glorious Summer by this son of York'

Received: Now is the winter of our discontent, made glorious Summer by this son of York

我应该在这里指出,这将是一个代码的 pig ,而不需要引入一些额外的库,就像@gushitong 所做的那样。

关于python - 通过 Python 套接字/WebSocket 客户端发送/接收 WebSocket 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43748377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com