You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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
  • 字段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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:05:19