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
Post a Comment