2013-08-19 220 views
6

我期待通过SPDY protocol脚本的一些基本请求。该协议将您发送的帧定义为由具有特定长度和字节顺序的二进制数据组成。通过Python发送二进制数据通过套接字

我只写过通过套接字(HTTP)发送字符串的小程序。例如,我如何去实现一个SPDY控制帧头?我已经尝试过使用bitstring库和numpy来控制控件框架头部的所有不同部分的大小,但是没有任何功能真正起作用。目前用于python的SPDY库使用了cython和C数据类型,我发现它非常不可预测。我想知道如何才能使用纯Python构建简单的请求,或者非常简单,我该如何建立一些类似于协议定义并通过套接字发送的东西?

回答

15

一般bytearray类将是你的朋友(如果我正确理解你的问题)。您可以通过套接字发送:

my_bytes = bytearray() 
my_bytes.append(123) 
my_bytes.append(125) 

// my_bytes is b'{}' now 

s.send(my_bytes) 

遵循协议规范并在字节后创建字节。当您收到数据这也适用于:

data = s.recv(2048) 
my_bytes = bytearray(data) 

我不知道很多关于SPDY协议,但例如控制位是消息中的第(不是字节)。您可以从my_bytes通过二进制和例如检索:

control_frame = my_bytes[0] & 128 

这是因为128是二进制10000000,因此二进制,只会给你的第一位(请记住,每个字节有8位,这就是为什么我们有7个零)。

这是如何手动完成的。当然,我建议使用一些库,因为编写一个合适的协议处理程序将花费很多时间,您可能会觉得它非常困难,并且可能效率不高(取决于您的需求)。

+0

谢谢我正在研究这个问题,如何将bytearray中的位打印为可读字符串,如果我将每个字符串初始化为0b ...? – ubiQ

+0

@ubiQ位? Bit只是0或1.如果你想打印一个bytearray,只需执行'print my_bytes'。 Python解释器应该自动将每个字节转换为其字符串表示形式。请注意,它可能不是“可读的”(取决于具体含义)。 – freakish

+0

我想在控制台中以字符串形式读取它,但它输出的是原始二进制数据atm – ubiQ

0

您也可以使用struct module来用字符串定义标题格式并直接解析它。

要生成的分组:

fmt = 'B I 4b' 
your_binary_data = pack(fmt, header_data) 
sock.sendall(your_binary_data) 

FMT指示报头格式( 'B I 4B' 仅仅是一个,显然不工作为您SPDY头,例如)。不幸的是,你将不得不处理非字节分配的头字段,可能是通过解析更大的块,然后根据你的格式进行分割。

除此之外,为了解析报头:

unpacker = struct.Struct('B I 4b') 
unpacked_data = unpacker.unpack(s.recv(unpacker.size)) 

unpacked_data将包含与所解析的数据元组。

结构模块在Python值和表示为Python字符串的C结构之间执行转换。我对这种方法的效率没有任何保证,但它帮助我通过调整字符串来解析不同的协议。

相关问题