Python编码Web套接字框架

时间:2016-11-17 20:49:19

标签: javascript python sockets websocket

我正在尝试在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"))的函数只接受缓冲区或字符串。

有没有人知道怎么做&#34;编码&#34;?

1 个答案:

答案 0 :(得分:1)

我没有关注这些( len(bytesRaw) >> 32 ) + 255行。 例如,如果您的有效负载长度为70&000;将执行else子句,为您提供一系列

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

这对我来说没什么意义。实际上,您提供的链接建议在您使用算术+ 时使用binary AND操作(如果您要对非重叠1和#的数字执行二进制OR,则可以使用+ 39; s是二进制形式,但不是用于做AND)。这些是非常不同的操作!

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

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

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

此外,请不要忘记,因为您使用TEXT帧,您的有效负载应该是有效的UTF-8字符串。有关详细信息,请参阅RFC 6455