struct模块能准确完成二进制协议的字节打包与拆解,但必须严格匹配协议定义的字节序、类型长度和字段顺序,稍有偏差就会读出错误数值或引发struct.error;pack和unpack的字节序须与协议一致,网络协议通常用大端(!),嵌入式设备常见小端(<)。

struct 模块能准确完成二进制协议的字节打包与拆解,但必须严格匹配协议定义的字节序、类型长度和字段顺序,稍有偏差就会读出错误数值或引发 struct.error。
struct.pack() 和 struct.unpack() 的字节序必须与协议一致
网络协议通常用大端(!),嵌入式设备常见小端(),主机本地默认(<code>=)不可靠。用错字节序会导致数值完全错误,比如 pack('>H', 0x1234) 得到 b'\x12\x34',而用 '<h> 会得到 <code>b'\x34\x12',两者在协议中含义不同。
- 协议文档写 “uint16 in network byte order” → 必须用
'!H' - 设备手册标 “little-endian int32” → 只能用
'<i>,不能用 <code>'i'(依赖平台) - 调试时可用
hex()打印 bytes 对象,比直接 print 更易比对原始字节
处理变长字段时 struct 本身不支持,需手动拼接
struct 要求格式字符串在调用前完全确定长度,无法直接处理「头部含长度字段 + 后跟 N 字节 payload」这类常见协议结构。强行用 unpack('!BH', data) 解出长度后,得用切片再取 payload。
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
- 典型流程:
header = unpack('!BH', data[:3])→ 得到消息类型和 payload 长度payload_len→ 再用data[3:3+payload_len]提取内容 - 不要试图写
'!BH{}s'.format(n)动态构造格式串——虽然语法合法,但 n 未知时无法预编译,且易引入格式串注入风险 - 若协议含多个变长字段,建议封装成函数,先 unpack 固定头,再按需 slice + decode
注意 C 类型与 Python 类型的隐式转换陷阱
struct 按 C ABI 解释字节,不校验值域。例如 'B'(unsigned char)接收 -1 会自动转为 255,'h'(signed short)传入 65535 会变成 -1,这些转换静默发生,极易埋下 bug。
立即学习“Python免费学习笔记(深入)”;
- 打包前务必检查值是否在目标类型的合法范围内:如
'B'→ 0–255,'h'→ -32768–32767 - 可写辅助函数做显式校验:
if not (0 - 浮点数用
'f'或'd'时,注意 IEEE 754 表示与 Python float 的精度一致性,不推荐用于高精度金融计算
最常被忽略的是填充字节(padding)——C 结构体对齐规则在 struct 中默认启用,但多数二进制协议是紧凑排列(no padding)。务必在格式字符串开头加 ''(空字符)或 '=' 显式禁用对齐,否则 pack('BH', 1, 2) 可能输出 4 字节(因 H 对齐到 2 字节边界),而非预期的 3 字节。

















