【问题标题】:Writing binary data to a socket (or file) with Python使用 Python 将二进制数据写入套接字(或文件)
【发布时间】:2009-03-27 00:16:57
【问题描述】:

假设我有一个套接字连接,而另一端的第 3 方侦听器希望看到数据以非常结构化的方式流动。例如,它查找一个表示正在发送的消息类型的无符号字节,然后是一个表示消息长度的无符号整数,然后是另一个无符号字节,它实际上是一个带有设置或未设置标志的位字段等。 .

我将如何在 python 中执行此操作?我只是想知道如何可靠地生成这些数据并确保我正确地发送它(即我真的在发送一个无符号字节而不是一个有符号整数或更糟的是一个字符串)。

【问题讨论】:

    标签: python


    【解决方案1】:

    使用struct 模块构建缓冲区并写入。

    【讨论】:

      【解决方案2】:

      处理 Python 对象和二进制表示(双向)之间的这些转换的一种非常优雅的方法是使用 Construct library

      在他们的文档中,您会发现许多使用它的好例子。几年来我自己一直在使用它来进行串行通信协议和解码二进制数据。

      【讨论】:

        【解决方案3】:

        在最低级别,套接字 I/O 包括读取或写入一串字节值到套接字。为此,我将要写入的信息编码为包含字节值的字符串,并将其写入套接字。我通过创建一个超字符串,然后一次附加一个字符来做到这一点。例如,创建一个 Modbus/Ethernet 读取请求:

            readRequest = """"""
            readRequest += chr(self.transactionID / 0x100)  # Transaction ID MSB         (0)
            readRequest += chr(self.transactionID % 0x100)  # Transaction ID LSB         (1)
            readRequest += chr(0)                           # Protocol ID MSB (Always 0) (2)
            readRequest += chr(0)                           # Protocol ID LSB (Always 0) (3)
            readRequest += chr(0)                           # Length MSB (Always 0)      (4)
            readRequest += chr(6)                           # Length LSB (Always 6)      (5)
            readRequest += chr(0)                           # Unit ID (Always 0)         (6)
        
            readRequest += chr(0x04)                        # Function code 4     (0)
            readRequest += chr(startOffset / 0x100)         # Starting offset MSB (1)
            readRequest += chr(startOffset % 0x100)         # Starting offset LSB (2)
            readRequest += chr(0)                           # Word count MSB      (3)
            readRequest += chr(2 * nToRead)                 # Word count LSB      (4)
        
            sockOutfile.write(readRequest)
        

        要将多字节值转换为字符串以便它们可以附加到 I/O 字符串上,请使用 struct 模块中的“Pack()”函数。此函数将一个或多个单字节或多字节值转换为一串单独的字节值。

        当然,这个方法和锤子一样简单。当字符串中的默认字符编码是 Unicode 而不是 ASCII 时,需要修复它。

        【讨论】:

        • 这不是一个好主意。它容易出错且难以维护。 struct 模块是一种更好的方法。
        • 是的,我必须同意。不幸的是,这是我在学习 Python 时写的,写得好像我还在用 C 写一样。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-15
        • 2014-09-29
        • 2013-05-29
        • 1970-01-01
        • 1970-01-01
        • 2020-02-25
        • 1970-01-01
        相关资源
        最近更新 更多