使用 Python 通过套接字发送二进制数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18310152/
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-08-19 10:27:20  来源:igfitidea点击:

Sending binary data over sockets with Python

pythonsockets

提问by ubiQ

I'm looking to script some basic requests over the SPDY protocol. The protocol defines the frames you send as being comprised of binary data of very specific length and byte order.

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

I've only ever written small programs that send strings across sockets (HTTP). How do I go about implementing a SPDY control frame header for example? I've tried using the bitstring library and numpy to control the size of all the different sections of a control frame header for example but nothing is really working. The current SPDY library for python uses cython and C data types and i've found it to be very unpredictable. I was wondering how I can go about building simple requests with pure python or very simply how do I go about building something precisely like the protocol defines and sending it across a socket?

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

采纳答案by freakish

Generally bytearrayclass will be your friend (if I understand your question correctly). You can send it via socket:

通常,bytearray班级将是您的朋友(如果我正确理解您的问题)。您可以通过套接字发送它:

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

// my_bytes is b'{}' now

s.send(my_bytes)

Follow the protocol specification and create byte after byte. This also works when you receive data:

遵循协议规范并逐个字节地创建。这在您接收数据时也有效:

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

I don't know much about SPDY protocol but for example the control bit is the first bit(not byte) in the message. You can retrieve it from my_bytesvia binary AND for example:

我对 SPDY 协议了解不多,但例如控制位是消息中的第一位(不是字节)。您可以my_bytes通过二进制 AND检索它,例如:

control_frame = my_bytes[0] & 128

this is because 128is 10000000in binary and thus binary AND will give you the first bit only (remember that each byte has 8 bits that's why we have 7 zeros).

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

That's how things are done manually. Of course I suggest using some library because writing a proper protocol handler will take lots of time, you may find it quite difficult and it might not be efficient (depending on your needs of course).

这就是手动完成的事情。当然我建议使用一些库,因为编写一个合适的协议处理程序会花费很多时间,你可能会发现这很困难,而且效率可能不高(当然取决于你的需要)。

回答by Niko

You can also use the struct moduleto define the header format with a string and parse it directly.

也可以使用struct 模块用字符串定义头格式并直接解析。

To generate a packet:

要生成数据包:

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

Where fmtindicates the header format ('B I 4b' is just a, clearly not working for your SPDY header, example). Unfortunately, you will have to deal with non-byte-alligned header fields, probably by parsing bigger chunks and then dividing them according to your format.

其中fmt表示标题格式('BI 4b' 只是一个,显然不适用于您的 SPDY 标题,例如)。不幸的是,您将不得不处理非字节对齐的标头字段,可能是通过解析更大的块然后根据您的格式划分它们。

Aside that, to parse the header:

除此之外,要解析标题:

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

unpacked_datawill contain a tuple with the parsed data.

unpacked_data将包含一个带有解析数据的元组。

The struct moduleperforms conversions between Python values and C structs represented as Python strings. I have no guarantees about the efficiency of this approach, but it helped me to parse different protocols just by adjusting the fmtstring.

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