ind*_*smo 9 c++ protocol-buffers boost-asio
我正在尝试通过TCP发送协议缓冲区消息,但在接收端,我在尝试解析时遇到"Missing required fields"错误,即使显然所有字段都在那里.我在包含消息长度的消息之前发送一个4字节的标头.
这是消息定义:
message ReplayRequest {
required string channel = 1;
required uint32 start = 2;
required uint32 end = 3;
}
Run Code Online (Sandbox Code Playgroud)
在客户端,我正在编写标题并将消息序列化为向量.
ReplayRequest req;
req.set_channel( "channel" )
req.set_start( 1 );
req.set_end( 5 );
int byte_size = req.ByteSize();
std::vector<uint8_t> write_buffer( HEADER_SIZE + byte_size );
encode_header( ... );
req.SerializeToArray( &write_buffer[HEADER_SIZE], byte_size );
Run Code Online (Sandbox Code Playgroud)
这是生成的缓冲区的十六进制打印,其中前4个字节是编码的消息长度(13个字节).
00 00 00 0d 0a 07 63 68 61 6e 6e 65 6c 10 01 18 05
Run Code Online (Sandbox Code Playgroud)
在服务器端,我收到标头,解码它然后接收N个字节,其中N是标头中报告的消息大小.删除标头的服务器中的缓冲区为:
0a 07 63 68 61 6e 6e 65 6c 10 01 18 05
Run Code Online (Sandbox Code Playgroud)
这与编码的客户端减去标题完全相同,但是当我尝试ParseFromArray这个缓冲区时,我得到一个错误:
libprotobuf ERROR c:\umdf_runtime\protobuf-2.4.1\src\google\protobuf\message_lit
e.cc:123] Can't parse message of type "ReplayRequest" because it is missing
required fields: channel, start, end
Run Code Online (Sandbox Code Playgroud)
调试时我注意到解码失败的地方是protobuf生成代码的这一部分:
bool ReplayRequest::IsInitialized() const {
if ((_has_bits_[0] & 0x00000007) != 0x00000007) return false;
return true;
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,has_bits_在服务器端被读为零,但我无法弄清楚原因.
有任何想法吗?
如果重要的话,我正在使用boost :: asio作为网络部分.
更新
根据要求,我发布了调用parseFromArray的代码.
request_.ParseFromArray( &data_buffer_, data_buffer_.size() );
Run Code Online (Sandbox Code Playgroud)
request_是一个ReplayRequest成员变量,直到此调用没有任何操作.
data_buffer_是接收TCP数据的向量<uint8_t>.
我确认它的大小正确为13个字节,这是它的十六进制转储,这与我在序列化后转储缓冲区客户端时得到的相同.
0a 07 63 68 61 6e 6e 65 6c 10 01 18 05
Run Code Online (Sandbox Code Playgroud)
更新2
我能够在客户端将缓冲区解析为另一个ReplayRequest实例,即:
...snip...
req.SerializeToArray( &write_buffer[HEADER_SIZE], byte_size );
ReplayRequest test;
test.ParseFromArray( &write_buffer[HEADER_SIZE], byte_size );
Run Code Online (Sandbox Code Playgroud)
使用正确的字段成功填充测试.
问题是你传入一个指向矢量的指针,而不是指向矢量数据的指针.
代替
request_.ParseFromArray( &data_buffer_, data_buffer_.size() );
尝试
request_.ParseFromArray( &data_buffer_[0], data_buffer_.size() );
| 归档时间: |
|
| 查看次数: |
8166 次 |
| 最近记录: |