Python解析Protobuf二进制数据返回值全为0的问题排查
Protobuf解码失败问题解决
问题根源
你直接用Values.Value类型解析二进制数据,但实际数据的最外层是Server消息(proto定义的根消息是Server),类型不匹配导致解析时忽略了所有有效字段,返回字段的默认值0。
二进制数据实际结构解析
你的十六进制数据1a170a1508c0d6b29f0610aaede3e40a21e90b21e7fdffef3f401a对应的Protobuf结构如下:
- 字段3(
msg中的Values):长度为0x17的嵌套消息- 字段1(
Values.values):长度为0x15的嵌套Value消息- 字段1(
timestamp):varint解码后为11234567890 - 字段2(
id):varint解码后为1234567890 - 字段4(
double_value):双精度浮点解码后为0.123456789
- 字段1(
- 字段1(
- 字段8(
ack_id):值为26
修正后的Python解码代码
import server_pb2 # 初始化最外层的Server消息 server_msg = server_pb2.Server() server_msg.ParseFromString(data) # 解析Values类型的消息 if server_msg.HasField("values"): for value in server_msg.values.values: print(f"timestamp: {value.timestamp}") print(f"id: {value.id}") # 判断oneof字段的实际类型 if value.HasField("string_value"): print(f"value: {value.string_value}") elif value.HasField("double_value"): print(f"value: {value.double_value}") elif value.HasField("int_value"): print(f"value: {value.int_value}") # 输出ack_id字段 print(f"ack_id: {server_msg.ack_id}")
预期输出
timestamp: 11234567890 id: 1234567890 value: 0.123456789 ack_id: 26
关键说明
- Protobuf解码必须匹配最外层的消息类型,否则会忽略不匹配的字段,返回默认值。
- 对于
oneof类型字段,需要用HasField()方法判断实际使用的子字段,避免访问未设置的字段获取默认值。
内容的提问来源于stack exchange,提问作者user22090909
相关产品推荐
相关产品推荐

