【问题标题】:Serialize and deserialize the message using google protobuf in socket programming in C++在 C++ 中的套接字编程中使用 google protobuf 序列化和反序列化消息
【发布时间】:2015-01-30 12:02:47
【问题描述】:

发送到服务器端的消息格式如下:

package test;

message Test {
  required int32 id = 1;
  required string name = 2;
}

Server.cpp 进行编码: 字符串缓冲区;

           test::Test original;
           original.set_id(0);
           original.set_name("original");

           original.AppendToString(&buffer);
           send(acceptfd,buffer.c_str(), buffer.size(),0);

通过这个发送函数,它会将数据发送给客户端,我希望并且对于这个特定的代码我也没有收到任何错误。

但我的担忧如下:

  1. 如何使用 Google 协议缓冲区对上述消息进行解码 客户端
  2. 这样我就可以看到/打印消息了。

【问题讨论】:

  • 你真的需要AppendToString() 吗?您是否将original 消息附加到任何其他消息?如果没有,你为什么不考虑 SerializeToString() ?我只是好奇。 (*)

标签: c++ sockets protocol-buffers


【解决方案1】:

您应该发送的不仅仅是 protobuf 消息,以便能够在客户端对其进行解码。

一个简单的解决方案是使用网络字节顺序将buffer.size() 的值作为 4 字节整数通过套接字发送,然后发送缓冲区本身。

客户端应首先从套接字读取缓冲区的大小,并将其从网络字节顺序转换为主机字节顺序。让我们表示结果值s。然后客户端必须预先分配一个大小为s 的缓冲区,并将s 字节从套接字读取到其中。之后,只需使用 MessageLite::ParseFromString 重构您的 protobuf。

有关 protobuf 消息方法的更多信息,请参阅 here

另外,this 文档不鼓励使用 required

您应该非常小心地根据需要标记字段。如果在 在某些时候您希望停止编写或发送必填字段,它 将字段更改为可选字段会有问题 - 旧 读者会认为没有此字段的消息不完整,并且 可能会无意中拒绝或丢弃它们。你应该考虑写 缓冲区的特定于应用程序的自定义验证例程 反而。谷歌的一些工程师得出的结论是 使用 required 弊大于利;他们更喜欢只使用 可选和重复。但是,这种观点并不普遍。

【讨论】:

  • 我只能打印 id 不能使用以下代码打印名称:
  • 您可能想使用 pastebin 来共享代码。评论并不是那么好。只需在 cmets 中发布 pastebin 链接即可。
  • 转到pastebin.com,将您的代码粘贴到文本字段中,然后单击提交。它会带你到一个新的页面。在 cmets 中将指向该页面的链接复制到此处。
  • 如何使用 google protobuf 对消息进行序列化/编码和反序列化/解码 ..任何想法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-15
  • 1970-01-01
  • 1970-01-01
  • 2016-07-19
  • 1970-01-01
  • 2013-05-29
相关资源
最近更新 更多