简体   繁体   English

在C ++中解析协议缓冲区

[英]Parsing protocol buffers in c++

I wanted to write some protocol buffers to the socket and read it back from the client side. 我想将一些协议缓冲区写入套接字,然后从客户端读取回去。 Things didn't work so I wrote some decoding part in the server itself right after I encoded it. 事情没有进行,所以我在对服务器进行编码后立即在服务器本身中编写了一些解码部分。 Can you please take a look at the code below and tell me what I am doing wrong ? 您能否看一下下面的代码,然后告诉我我做错了什么?

(I had to use arraystream and coded stream so that I can write a delimiter) (我必须使用arraystream和编码流,以便可以编写定界符)

int bytes_written = tData.ByteSize() + sizeof(google::protobuf::uint32);
google::protobuf::uint8 buffer[bytes_written];
memset(buffer, '\0', bytes_written);
google::protobuf::io::ArrayOutputStream aos(buffer,bytes_written);
google::protobuf::io::CodedOutputStream *coded_output = new google::protobuf::io::CodedOutputStream(&aos);
google::protobuf::uint32 size_  = tData.ByteSize();
coded_output->WriteVarint32(size_);

tData.SerializeToCodedStream(coded_output);

int sent_bytes = 0;
std::cout << buffer << std::endl;
if ( (sent_bytes = send(liveConnections.at(i), buffer, bytes_written, MSG_NOSIGNAL)) == -1 )
    liveConnections.erase(liveConnections.begin() + i);
else
    std::cout << "sent "  << sent_bytes << " bytes to " << i << std::endl;

delete coded_output;



////////////////


google::protobuf::uint8 __buffer[sizeof(google::protobuf::uint32)];
memset(__buffer, '\0', sizeof(google::protobuf::uint32));
memcpy (__buffer, buffer, sizeof(google::protobuf::uint32));

google::protobuf::uint32 __size = 0;

google::protobuf::io::ArrayInputStream ais(__buffer,sizeof(google::protobuf::uint32));
google::protobuf::io::CodedInputStream coded_input(&ais);
coded_input. ReadVarint32(&__size);
std::cout <<" size of payload is "<<__size << std::endl;

google::protobuf::uint8 databuffer[__size];
memset(databuffer, '\0', __size);
memcpy (databuffer, buffer+sizeof(google::protobuf::uint32), __size);    

std::cout << "databuffs " << "size " << __size << "  "<< databuffer << std::endl;
google::protobuf::io::ArrayInputStream array_input(databuffer,__size);
google::protobuf::io::CodedInputStream _coded_input(&array_input);
data_model::terminal_data* tData = new data_model::terminal_data();
if (!tData->ParseFromCodedStream(&_coded_input))
{
    std::cout << "data could not be parsed" << std::endl;     
}
else
{
    std::cout <<" SYMBOL --" << tData->symbol_name() << std::endl;
}
delete tData;

Out put of the program: 程序输出:

size of payload is 55
databuffs size 55  C109"056*    BANKNIFTY0���20140915@�J    145406340
data could not be parsed
C109"056*   BANKNIFTY0���20140915@�J    145406340

WriteVarint32 doesn't necessarily write 4 bytes, and ReadVarint32 doesn't read 4 bytes. WriteVarint32不一定要写入4个字节,而ReadVarint32不必读取4个字节。 "Var" stands for "variable", as in "variable length encoding". 如“可变长度编码”中一样,“ Var”代表“变量”。

When encoding, you write the size (which can take as little as one byte), then immediately the proto. 编码时,您写出大小(可能只有一个字节),然后写出原型。 When decoding, you read the size, then advance by four bytes, then read the proto. 解码时,您读取大小,然后前进四个字节,然后读取原型。 So, you are parsing starting from the wrong offset. 因此,您是从错误的偏移量开始解析。

Use CurrentPosition() after ReadVarint32 to figure out how many bytes the size indicator consumed. ReadVarint32之后使用CurrentPosition()来计算大小指示器消耗了多少字节。 Advance by that number of bytes. 前进该字节数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM