【问题标题】:Python encode web socket framesPython 编码网络套接字帧
【发布时间】:2016-11-18 16:47:18
【问题描述】:

我正在尝试在 javascript 客户端和 python 服务器之间建立 Web 套接字连接。我已经设法正确地握手,我可以从 javascript 客户端发送数据,并在服务器上对其进行解码。

当我想从服务器发送数据时出现问题。当我尝试发送清晰的 ascii 文本时,我在客户端 Websocket Error: [object Event] 上收到此错误。自然,所以我想在发送数据之前对其进行“编码”。我尝试了很多东西,包括基本的base64。但没有任何效果。我偶然发现了这个thread。这是一个如何准备发送数据的示例。

这是我目前想出的代码:

def encodeFrame(bytesRaw):
bytesFormatted = []
bytesFormatted.append(129)

indexStartRawData = 0

if len(bytesRaw) <= 125:
    bytesFormatted.append(len(bytesRaw))

    indexStartRawData = 2

elif len(bytesRaw) >= 126 and len(bytesRaw) <= 65535:
    bytesFormatted.append(126)
    bytesFormatted.append(( len(bytesRaw) >> 8 ) + 255)
    bytesFormatted.append(( len(bytesRaw) ) + 255)

    indexStartRawData = 4

else:
    bytesFormatted.append(127)
    bytesFormatted.append(( len(bytesRaw) >> 56 ) + 255)
    bytesFormatted.append(( len(bytesRaw) >> 48 ) + 255)
    bytesFormatted.append(( len(bytesRaw) >> 40 ) + 255)
    bytesFormatted.append(( len(bytesRaw) >> 32 ) + 255)
    bytesFormatted.append(( len(bytesRaw) >> 24 ) + 255)
    bytesFormatted.append(( len(bytesRaw) >> 16 ) + 255)
    bytesFormatted.append(( len(bytesRaw) >> 8 ) + 255)
    bytesFormatted.append(( len(bytesRaw) ) + 255)

    indexStartRawData = 10

bytesFormatted.put(bytesRaw, indexStartRawData)

return bytesFormatted

我认为大部分都可以正常工作,但我不知道我应该如何处理最后一个命令:bytesFormatted.put(bytesRaw, indexStartRawData)。我试过只是附加到数组,并使用缓冲区格式。但它不会起作用。在我的例子中,发送数据 client.send(encodeFrame("test")) 的函数只需要一个缓冲区或字符串。

有人知道如何进行这种“编码”吗?

【问题讨论】:

    标签: javascript python sockets websocket


    【解决方案1】:

    我没有关注这些( len(bytesRaw) &gt;&gt; 32 ) + 255 行。 例如,如果你的有效载荷长度是 70'000,else 子句将被执行,给你一个序列

    [127, 255, 255, 255, 255, 255, 256, 528, 70255]
    

    这对我来说没有多大意义。实际上,您提供的链接建议在使用 arithmetic + 时使用 binary AND 操作(如果您要对具有非重叠 1 的二进制形式的数字执行二进制 OR,则可以使用 +,但是不是为了做AND)。这些是非常不同的操作!

    虽然您可以使用( len(bytesRaw) &gt;&gt; 32 ) &amp; 255,但它不能保证该数字将是一个字节长 - 由解释器决定如何存储它。为了克服这个问题,python 中的struct 模块用于组装二进制数据。例如,整个else 子句折叠为struct.pack('B', 127) + struct.pack('!Q', len(bytesRaw))! 表示网络字节顺序(大端),Q 表示 8 字节无符号整数,B 表示无符号字节。

    即使你不想用struct 重写代码(我当然不坚持),目前你从encodeFrame 函数返回一个list。您不能通过网络发送列表。可以发送 C 数组,但是 Python 列表是一个非常复杂的对象,不能这样发送。您需要先将其转换为字节序列:

    def list_to_bytes(lst):
        format = 'B' * len(lst)
        return struct.pack(format, *lst)
        
    

    此外,由于您使用 TEXT 帧,因此请不要忘记您的有效负载应该是有效的 UTF-8 字符串。详情请参考RFC 6455

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-04
      • 1970-01-01
      • 1970-01-01
      • 2013-03-18
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      相关资源
      最近更新 更多