13

C++ でソケット接続を介して送信するメッセージをシリアル化するために protobuf を使用しています。通信のために、メッセージの長さを示すヘッダーをメッセージに追加したいと思います。この実装についてどう思いますか?私はいくつかの研究を行い、それをまとめました。

これを行うためのより良い方法はありますか?この実装は問題を引き起こす可能性がありますか? Java の API サポートがあることは知っていますが、残念ながら 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;
}
4

1 に答える 1

7

WriteVarint32fixed32 ( がある場合) よりも varint (例: ) を使用する方が一般的ですがWriteLittleEndian32、長さのプレフィックスを付けて protobuf ストリームを区切る方法は適切です。

于 2012-07-25T00:09:06.507 に答える