解析c++中的协议缓冲区

Parsing protocol buffers in c++

本文关键字:协议 缓冲区 c++ 解析      更新时间:2023-10-16

我想写一些协议缓冲区到套接字,并从客户端读取它。事情没有工作,所以我写了一些解码部分在服务器本身后,我编码它。你能看看下面的代码,告诉我我做错了什么吗?

(我必须使用arraystream和coded stream,这样我才能写一个分隔符)

int bytes_written = tData.ByteSize() + sizeof(google::protobuf::uint32);
google::protobuf::uint8 buffer[bytes_written];
memset(buffer, '', 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, '', 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, '', __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;

程序输出:

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不一定写入4字节,ReadVarint32也不一定读取4字节。"Var"代表"可变",如"可变长度编码"。

编码时,先写入大小(可以少到一个字节),然后立即写入原型。解码时,读取大小,然后向前推进四个字节,然后读取原型。因此,您从错误的偏移量开始解析。

ReadVarint32之后使用CurrentPosition()来计算大小指示器消耗了多少字节。