【问题标题】:Sending binary data over sockets with Python使用 Python 通过套接字发送二进制数据
【发布时间】:2013-08-21 00:49:43
【问题描述】:

我正在寻找通过SPDY protocol 编写一些基本请求的脚本。该协议将您发送的帧定义为由非常特定长度和字节顺序的二进制数据组成。

我只编写过通过套接字 (HTTP) 发送字符串的小程序。例如,我该如何实现 SPDY 控制帧头?例如,我尝试使用位串库和 numpy 来控制控制帧头的所有不同部分的大小,但没有任何效果。当前用于 python 的 SPDY 库使用 cython 和 C 数据类型,我发现它非常不可预测。我想知道如何使用纯 python 构建简单的请求,或者非常简单地如何构建与协议定义完全相同的内容并通过套接字发送?

【问题讨论】:

    标签: python sockets


    【解决方案1】:

    通常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 协议了解不多,但例如控制位是消息中的第一个 (不是字节)。您可以通过二进制 AND 从my_bytes 检索它,例如:

    control_frame = my_bytes[0] & 128
    

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

    这就是手动完成的方式。当然我建议使用一些库,因为编写适当的协议处理程序会花费大量时间,您可能会发现它非常困难并且可能效率不高(当然取决于您的需求)。

    【讨论】:

    • 谢谢我正在调查这个问题,如果我将字节数组中的位初始化为 0b...,如何将字节数组中的位打印为可读字符串?
    • @ubiQ 位?位只是 0 或 1。如果要打印字节数组,只需执行 print my_bytes。 Python 解释器应自动将每个字节转换为其字符串表示形式。请注意,它可能不是“可读的”(取决于它的确切含义)。
    • 我想在控制台中将其作为字符串读取,但它输出的是原始二进制 atm
    • @ubiQ 你到底在那个数组里放了什么?给我看一些代码。请注意,只有 32 到 126 之间的字节是可打印的 (ASCII)。
    • control_header = bytearray()control_header.append(0b1)#control_flag control_header.append(0b00000000000000013)#typector_hipper.append(0b000000000000000001)#type control_header.append(0b000000000000000000/borcs control_header.append(0b000000000000 ) # 长度打印 my_bytes
    【解决方案2】:

    也可以使用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 将包含一个带有已解析数据的元组。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-23
      • 2012-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 1970-01-01
      相关资源
      最近更新 更多