13

I'm using protobuf to serialize message I send over a socket connection in C++. For the communication I'd like to add a header to the messags indicating the length of the message. What do you think about this implementation? I did some research and that's what I put together.

Is there any nicer way to do this? Can this implementation cause any trouble? I know that there is API support for Java, but unfortunately not for C++.

bool send_message(int socket, my_protobuf::Message message)
{
  google::protobuf::uint32 message_length = message.ByteSize();
  int prefix_length = sizeof(message_length);
  int buffer_length = prefix_length + message_length;
  google::protobuf::uint8 buffer[buffer_length];

  google::protobuf::io::ArrayOutputStream array_output(buffer, buffer_length);
  google::protobuf::io::CodedOutputStream coded_output(&array_output);

  coded_output.WriteLittleEndian32(message_length);
  message.SerializeToCodedStream(&coded_output);

  int sent_bytes = write(socket, buffer, buffer_length);
  if (sent_bytes != buffer_length) {
    return false;
  }

  return true;
}

bool recv_message(int socket, my_protobuf::Message *message)
{
  google::protobuf::uint32 message_length;
  int prefix_length = sizeof(message_length);
  google::protobuf::uint8 prefix[prefix_length];

  if (prefix_length != read(socket, prefix, prefix_length)) {
    return false;
  }
  google::protobuf::io::CodedInputStream::ReadLittleEndian32FromArray(prefix,
      &message_length);

  google::protobuf::uint8 buffer[message_length];
  if (message_length != read(socket, buffer, message_length)) {
    return false;
  }
  google::protobuf::io::ArrayInputStream array_input(buffer, message_length);
  google::protobuf::io::CodedInputStream coded_input(&array_input);

  if (!message->ParseFromCodedStream(&coded_input)) {
    return false;
  }

  return true;
}
multiholle
  • 3,050
  • 8
  • 41
  • 60
  • 1
    see this [answer](http://stackoverflow.com/questions/2340730/are-there-c-equivalents-for-the-protocol-buffers-delimited-i-o-functions-in-ja) – alavrik Jul 25 '12 at 14:21
  • is it necessary that the buffer be of unsigned int8 type ? – Chani Aug 18 '14 at 20:28
  • How does your socket->write() accept buffer of google::protobuf::uint8 type ? – Chani Aug 18 '14 at 20:28

1 Answers1

7

It's more common to use varint (e.g. WriteVarint32) rather than fixed32 (where you have WriteLittleEndian32), but the practice of delimiting protobuf streams by prefixing with length is sound.

ephemient
  • 198,619
  • 38
  • 280
  • 391