大家好我有两段代码,令我困惑的是,虽然它们应该是等价的,但是在运行这两段代码时我没有收到相同的结果,它们之间有什么区别?
这是第一个和工作部分:
packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload
和第二个非工作部分:
# packet = struct.pack(">B", relayCmd)
# packet += struct.pack("H", 0)
# packet += struct.pack("H", streamId)
# packet += struct.pack("L", 0)
# packet += struct.pack("H", len(payload))
# packet += payload
答案 0 :(得分:2)
在第一个版本中,您通过“>”指定Big Endian的格式然后所有格式参数都以这种方式编码。在第二个示例中,仅在第一行中指定Big Endian,然后使用系统的 native 编码对所有其他参数进行编码(默认使用“@”)。
答案 1 :(得分:1)
来自struct
文档:
注意:默认情况下,打包给定C结构的结果包括填充字节,以便维护所涉及的C类型的正确对齐;类似地,在拆包时考虑对齐。选择此行为,以便打包结构的字节与相应C结构的内存中的布局完全对应。要处理与平台无关的数据格式或省略隐式填充字节,请使用
standard
大小和对齐而不是native
大小和对齐:有关详细信息,请参阅字节顺序,大小和对齐。
如果未指定其他4行的对齐方式,则使用默认的@
对齐(使用native
对齐方式)。您只对第一个>
代码点使用了relayCmd
标准对齐方式。
因此,产生的尺寸是不同的:
>>> import struct
>>> struct.calcsize('>BHHLH')
11
>>> struct.calcsize('>B')
1
>>> struct.calcsize('H')
2
>>> struct.calcsize('L')
8
>>> 1 + 3 * 2 + 8
15
不同之处在于填充L
;如果您对所有 >
次调用使用pack()
大端标记,则只需四个字节:
>>> struct.calcsize('>L')
4
这样可行:
packet = struct.pack(">B", relayCmd)
packet += struct.pack(">H", 0)
packet += struct.pack(">H", streamId)
packet += struct.pack(">L", 0)
packet += struct.pack(">H", len(payload))
packet += payload
答案 2 :(得分:1)
你必须在每个字母前加上>
,所以一切都是大端的。
#!/usr/bin/env python2
import struct
relayCmd = 170
streamId = 10000
payload = "A"
packet = struct.pack(">BHHLH", relayCmd, 0, streamId, 0, len(payload)) + payload
print(''.join("{:02x} ".format(ord(i)) for i in packet))
packet = struct.pack(">B", relayCmd)
packet += struct.pack(">H", 0)
packet += struct.pack(">H", streamId)
packet += struct.pack(">L", 0)
packet += struct.pack(">H", len(payload))
packet += payload
print(''.join("{:02x} ".format(ord(i)) for i in packet))