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

标签 c++ sockets message protocol-buffers

我正在使用 protobuf 序列化我通过 C++ 中的套接字连接发送的消息。对于通信,我想在消息中添加一个 header ,指示消息的长度。你怎么看这个实现?我做了一些研究,这就是我总结的结果。

有没有更好的方法来做到这一点?这个实现会引起任何麻烦吗?我知道有对 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;
}

最佳答案

更常见的是使用 varint(例如 WriteVarint32)而不是 fixed32(您有 WriteLittleEndian32),但是通过以长度为前缀来分隔 protobuf 流的做法是合理的.

关于c++ - C++ 中 protobuf 消息的长度前缀,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11640864/

相关文章:

C UDP套接字,在recvfrom检索之前数据包存储在哪里?

.net - 套接字对比周转基金

dataframe - Pyspark:序列化任务超过允许的最大值。考虑增加 spark.rpc.message.maxSize 或对大值使用广播变量

c++ - apply_visitor 不改变对象

c++ - 为什么在 constexpr 非成员函数中访问全局非常量变量是不合法的

c++ - 如何懒惰地生成一个完成的项目序列并对其进行迭代

sockets - 关闭 TCP 套接字的二郎

c++ - 链接 CMakeLists : ld cannot find library

c++ - MFC CFormView OnKeyDown 事件未触发

jquery - 使用 jquery 的类似 Twitter 的状态消息