从 nanopb 读取 Proto Buffer 消息时出现 DecodeError
DecodeError when reading Proto Buffer message from nanopb
我为 IoT 设备实现了一个小型 HttpClient,并希望使用 Proto Buffer 作为通信格式。由于平台的限制,我使用的是 nanopb。那是 C:
中的相关代码
#include <pb_encode.h>
#include "device_data.pb.h"
#include <ESP8266HTTPClient.h>
[...]
pb_MEvent m_event = pb_MEvent_init_zero;
uint8_t m_buffer[21];
pb_ostream_t stream = pb_ostream_from_buffer(m_buffer, 21);
pb_encode(&stream, pb_MEvent_fields, &m_event);
int httpCode = httpClient.POST(m_buffer, stream.bytes_written);
[...]
我创建了一个暴露端点的小型烧瓶服务器。当我尝试解码消息时,出现以下错误:google.protobuf.message.DecodeError: Error parsing message with type 'pb.MEvent'
它的代码:
from flask import Flask, request
from device_data_pb2 import MEvent
app = Flask(__name__)
@app.route("/", methods = ['POST', "GET"])
def hello_world():
m_event = MEvent()
m_event.ParseFromString(request.data)
print(m_event)
if __name__ == '__main__':
app.run(host='0.0.0.0', port= 5000)
我尝试使用 io.ByteStream 然后阅读它,我还尝试使用 ASCII 和 UTF-8 对字节进行编码,但这两种方法都不起作用。
你能帮我看看是什么问题造成的吗?错误消息没有太大帮助。
更新
这是原型文件的内容:
syntax = "proto2";
package pb;
message MEvent {
required float accelX = 1;
required float accelY = 2;
required float accelZ = 3;
required float gyroX = 4;
required float gyroY = 5;
required float gyroZ = 6;
required int64 msec = 7;
}
这里有一些数据点:
DATA:
0.16 -0.08 9.96 0.00 -0.00 0.02 0
HEX:
0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d
DATA:
0.16 -0.09 9.96 0.00 -0.00 0.02 0
HEX:
0d:cd:7d:20:3e:15:56:ab:bc:bd:1d:5f:6b:1f:41:25:79:22:a0:3b:2d
DATA:
0.15 -0.10 9.96 0.00 -0.00 0.02 0
HEX:
0d:89:0a:1e:3e:15:21:05:c4:bd:1d:de:52:1f:41:25:b5:33:70:3b:2d
DATA: 0.16 -0.08 9.96 0.00 -0.00 0.02 0
HEX: 0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d
我正在使用 nanopb/tests/raw_decode
来分析这个。 Marc Gravell 的 decode utility 曾经非常适合这个,但出于某种原因,它不再适用于损坏的数据。
user@host:~/nanopb/tests$ echo 0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d \
| tr -d ':' | xxd -r -p | build/raw_decode/raw_decode
At 0: field tag 1, wire type 5 (32BIT), fixed32 value (4 bytes): 0x3e27d798
At 5: field tag 2, wire type 5 (32BIT), fixed32 value (4 bytes): 0xbdadf7bf
At 10: field tag 3, wire type 5 (32BIT), fixed32 value (4 bytes): 0x411f7046
At 15: field tag 4, wire type 5 (32BIT), fixed32 value (4 bytes): 0x3b7033b5
At 20: field tag 5, wire type 5 (32BIT)
ERROR: Failed to parse fixed32: io error
LATEST BYTES READ (21 to 21):
看来你的留言被打断了。
您在此行预留的缓冲区量 space 不够大:
uint8_t m_buffer[21];
如果您检查 pb_encode()
的 return 值,它可能也在 returning false
并且 stream.errmsg
表示缓冲区已满。
我为 IoT 设备实现了一个小型 HttpClient,并希望使用 Proto Buffer 作为通信格式。由于平台的限制,我使用的是 nanopb。那是 C:
中的相关代码#include <pb_encode.h>
#include "device_data.pb.h"
#include <ESP8266HTTPClient.h>
[...]
pb_MEvent m_event = pb_MEvent_init_zero;
uint8_t m_buffer[21];
pb_ostream_t stream = pb_ostream_from_buffer(m_buffer, 21);
pb_encode(&stream, pb_MEvent_fields, &m_event);
int httpCode = httpClient.POST(m_buffer, stream.bytes_written);
[...]
我创建了一个暴露端点的小型烧瓶服务器。当我尝试解码消息时,出现以下错误:google.protobuf.message.DecodeError: Error parsing message with type 'pb.MEvent'
它的代码:
from flask import Flask, request
from device_data_pb2 import MEvent
app = Flask(__name__)
@app.route("/", methods = ['POST', "GET"])
def hello_world():
m_event = MEvent()
m_event.ParseFromString(request.data)
print(m_event)
if __name__ == '__main__':
app.run(host='0.0.0.0', port= 5000)
我尝试使用 io.ByteStream 然后阅读它,我还尝试使用 ASCII 和 UTF-8 对字节进行编码,但这两种方法都不起作用。
你能帮我看看是什么问题造成的吗?错误消息没有太大帮助。
更新
这是原型文件的内容:
syntax = "proto2";
package pb;
message MEvent {
required float accelX = 1;
required float accelY = 2;
required float accelZ = 3;
required float gyroX = 4;
required float gyroY = 5;
required float gyroZ = 6;
required int64 msec = 7;
}
这里有一些数据点:
DATA:
0.16 -0.08 9.96 0.00 -0.00 0.02 0
HEX:
0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d
DATA:
0.16 -0.09 9.96 0.00 -0.00 0.02 0
HEX:
0d:cd:7d:20:3e:15:56:ab:bc:bd:1d:5f:6b:1f:41:25:79:22:a0:3b:2d
DATA:
0.15 -0.10 9.96 0.00 -0.00 0.02 0
HEX:
0d:89:0a:1e:3e:15:21:05:c4:bd:1d:de:52:1f:41:25:b5:33:70:3b:2d
DATA: 0.16 -0.08 9.96 0.00 -0.00 0.02 0 HEX: 0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d
我正在使用 nanopb/tests/raw_decode
来分析这个。 Marc Gravell 的 decode utility 曾经非常适合这个,但出于某种原因,它不再适用于损坏的数据。
user@host:~/nanopb/tests$ echo 0d:98:d7:27:3e:15:bf:f7:ad:bd:1d:46:70:1f:41:25:b5:33:70:3b:2d \ | tr -d ':' | xxd -r -p | build/raw_decode/raw_decode At 0: field tag 1, wire type 5 (32BIT), fixed32 value (4 bytes): 0x3e27d798 At 5: field tag 2, wire type 5 (32BIT), fixed32 value (4 bytes): 0xbdadf7bf At 10: field tag 3, wire type 5 (32BIT), fixed32 value (4 bytes): 0x411f7046 At 15: field tag 4, wire type 5 (32BIT), fixed32 value (4 bytes): 0x3b7033b5 At 20: field tag 5, wire type 5 (32BIT) ERROR: Failed to parse fixed32: io error LATEST BYTES READ (21 to 21):
看来你的留言被打断了。 您在此行预留的缓冲区量 space 不够大:
uint8_t m_buffer[21];
如果您检查 pb_encode()
的 return 值,它可能也在 returning false
并且 stream.errmsg
表示缓冲区已满。