0

I'm using protocol buffers for c++ to generate a string that should be send over the network. But when calling ParseFromString I receive false as return and no error message!?

I create the object to be send as follows:

Messages::RequestMessage msg;
msg.set_type(1);
msg.set_epid(4);

string s;
if (msg.SerializeToString(&s)) {
    Log("serialized");
    return s;
} else {
    Log("error serializing", log::error);
    return "";
}

The generated string should now be send via async_write from boost::asio over the network. I have tried different approaches here:

max_length = 1024;
char data_[max_length];
memset(data_, '\0', sizeof(char)*max_length);

//first tried 
//const char *msg = s.c_str();
//memcpy(data_, msg, strlen(msg));

memcpy(data_, s.data(), s.size());

boost::asio::async_write(socket_, boost::asio::buffer(data_, max_length),
                                  boost::bind(&Session::handle_write, this,
                                  boost::asio::placeholders::error));

And on the receiver side:

char reply_[max_length];
boost::asio::async_read(socket_, boost::asio::buffer(reply_, max_length),
                            boost::bind(&Client::handle_read, this,
                            boost::asio::placeholders::error,
                            boost::asio::placeholders::bytes_transferred));

string str(reply_);

Messages::RequestMessage m;
bool ret = m.ParseFromString(str);
//which gives ret=false but no error msg is displayed!?

I think there might be something wrong with transforming the string into char* and back?

wasp256
  • 5,943
  • 12
  • 72
  • 119
  • The right tool to solve such problems is your debugger. You should step through your code line-by-line *before* asking on Stack Overflow. For more help, please read [How to debug small programs (by Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). At a minimum, you should \[edit] your question to include a [Minimal, Complete, and Verifiable](http://stackoverflow.com/help/mcve) example that reproduces your problem, along with the observations you made in the debugger. – πάντα ῥεῖ Dec 27 '16 at 19:12
  • you have to add some framing protocol around your encoded messages. protocol buffers does not do this for you – Richard Hodges Dec 27 '16 at 19:15
  • What do you mean by framing protocol? – wasp256 Dec 27 '16 at 19:16
  • As @Richard said. Easiest is to send the message length ahead. `async_read()` doesn't guarantee that the data sent is received in one go. – πάντα ῥεῖ Dec 27 '16 at 19:16
  • Why do I need to send the length ahead, shouldn't I be able to convert the string into the char* to sent and back when receiving it? – wasp256 Dec 27 '16 at 19:18
  • Let's the master magician of _protocol buffers_ give an answer. As mentioned _"async_read() doesn't guarantee that the data sent is received in one go"_, you have to receive the whole message before parsing it. – πάντα ῥεῖ Dec 27 '16 at 19:20
  • Is there a better approach instead of having to send the size ahead? – wasp256 Dec 27 '16 at 19:23
  • _"Is there a better approach instead of having to send the size ahead?"_ No, not really. – πάντα ῥεῖ Dec 27 '16 at 19:24
  • 2
    if you don't know what a framing protocol is you're not ready to be sending messages across a network connection. It's a fundamental requirement. Sorry to be blunt, but you need to know. – Richard Hodges Dec 27 '16 at 19:26
  • @wasp256 Besides sending the length of message ahead, most framing protocols support a checksum sent ahead also. Thus you can verify the message data was transported correctly. – πάντα ῥεῖ Dec 27 '16 at 19:30

0 Answers0