使用 Python 将二进制数据写入套接字(或文件)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/686296/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 20:38:08  来源:igfitidea点击:

Writing binary data to a socket (or file) with Python

python

提问by Tuxmentat

Let's say I have a socket connection, and the 3rd party listener on the other side expects to see data flowing in a very structured manner. For example, it looks for an unsigned byte that denotes a type of message being sent, followed by an unsigned integer that denotes the length of message, then another unsigned byte which is really a bit field with some flags set or unset and etc...

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

How would I do this in python? I'm just wondering how to reliably generate this data and make sure I'm sending it correctly (i.e. that I'm really sending an unsigned byte rather than say a signed integer or worse, a string).

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

回答by S.Lott

Use the structmodule to build a buffer and write that.

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

回答by Ber

A very elegant way to handle theses transitions between Python objects and a binary representation (both directions) is using the Construct library.

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

In their documentation you'll find many nice examples of using it. I've been using it myself for several years now for serial communications protocols and decoding binary data.

在他们的文档中,您会找到许多使用它的好例子。我自己已经使用它好几年了,用于串行通信协议和解码二进制数据。

回答by mkClark

At the lowest level, socket I/O consists of reading or writing a string of byte values to a socket. To do this, I encode the information to be written as a string of characters containing the byte values, and write it to the socket. I do this by creating a superstring, and then appending one character at a time. for example, to create a Modbus/Ethernet read request:

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

    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)

To convert multibyte values into character strings so they can be appended onto the I/O string, use the 'Pack()' function in the struct module. This function converts one or more single or multiple byte values into a string of individual byte values.

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

Of course, this method is about as simple as a hammer. It will need to be fixed when the default character encoding in a string is Unicode instead of ASCII.

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