2016-11-17 96 views
0

我试图做一个JavaScript客户端和python服务器之间的网络套接字连接。我已经成功地握手了,我可以从JavaScript客户端发送数据,并在服务器上解码。Python编码网络套接字框架

当我想从服务器发送数据时出现问题。当我尝试发送明确的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"))在我的情况下,只需要一个缓冲区或字符串。

有没有人有任何想法如何做到这一点“编码”?

回答

1

我没有关注这些(len(bytesRaw) >> 32) + 255行。 举例来说,如果你的有效载荷长度为70'000,else子句就会执行,给你的

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

这是一个顺序没有多大意义的我。实际上,您提供的链接建议使用binary AND操作,而您使用算术+(如果要对二进制形式的非重叠1进行二进制或运算,则可以使用+,但对于进行AND操作不适用)。这些是非常不同的操作!

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

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

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

同时,请不要忘记,你的有效载荷应该是一个有效的UTF-8字符串,因为你使用文本框。详情请参阅RFC 6455

+0

谢谢,完美的作品! – jakobS