C++ Linux Google Protobuf + boost::asio Cannot Parse -


i trying send google protobuf message on boost::asio socket via tcp. recognize tcp streaming protocol , performing length-prefixing on messages before go through socket. have code working, appears work of time, though i'm repeating same calls , not changing environment. on occasion receive following error:

[libprotobuf error google/protobuf/message_lite.cc:123] can't parse message of type "xxx" because missing required fields: name, applicationtype, messagetype

the reason easy understand, cannot single out why occurs , parses fine majority of time. easy duplicate error having single client talking server , restarting processes.

below socket code snippets.

const int tcp_header_size = 8;

sender:

bool write(const google::protobuf::messagelite& proto) {     char header[tcp_header_size];     int size = proto.bytesize();     char data[tcp_header_size + size];     sprintf(data, "%i", size);     proto.serializetoarray(data+tcp_header_size, size);     boost::asio::async_write(socket,                               boost::asio::buffer(data, tcp_header_size + size),                              boost::bind(&tcpsender::writehandler,                                           this, _1, _2)); } 

receiver:

std::array<char, tcp_header_size> header; std::array<char, 8192> bytes;  void readhandler(const boost::system::error_code &ec,                   std::size_t bytes_transferred) {     if(!ec) {         int msgsize = atoi(header.data());         if(msgsize > 0) {             boost::asio::read(socket, boost::asio::buffer(bytes,static_cast<std::size_t>(msgsize)));             readfunc(bytes.data(), msgsize);         }         boost::asio::async_read(socket, boost::asio::buffer(header, tcp_header_size),                                 boost::bind(&tcpreceiver::readhandler, this, _1, _2));     }     else {         std::cerr << "server::readhandler::" << ec.message() << '\n';     } } 

readfunc:

void handleincomingdata(const char *data, const std::size_t size) {     xxx::messaging::cmsmessage proto;     proto.parsefromarray(data, static_cast<int>(size)); } 

i should mention need fast possible, optimizations appreciated well.

the program invokes undefined behavior fails meet lifetime requirement boost::asio::async_write()'s buffers parameter:

[...] ownership of underlying memory blocks retained caller, must guarantee remain valid until handler called.

within write() function, boost::asio::async_write() return immediately, , potentially cause data go out of scope before asynchronous write operation has completed. resolve this, consider expanding life of underlying buffer, such associating buffer operation , performing cleanup in handler, or making buffer data member on tcpsender.


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -