C++中protobuf消息的长度前缀

13

我正在使用protobuf在C++中序列化发送到套接字连接上的消息。为了通信,我想要在消息中添加一个指示消息长度的头部。你对这种实现有什么看法?我做了一些研究并拼凑出了这个方案。

有没有更好的方法来做这件事?这种实现会引起什么问题吗?我知道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;
}

1
请查看此答案 - alavrik
缓冲区一定要是无符号8位整数类型吗? - Chani
你的socket->write()如何接受google::protobuf::uint8类型的缓冲区? - Chani
1个回答

7

通常使用varint(例如WriteVarint32)而不是fixed32(其中有WriteLittleEndian32),但在protobuf流中添加长度前缀的做法是正确的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接