如何通过套接字发送.proto(协议缓冲区)中定义的类

Posted

技术标签:

【中文标题】如何通过套接字发送.proto(协议缓冲区)中定义的类【英文标题】:how to send classes defined in .proto (protocol-buffers) over a socket 【发布时间】:2010-03-12 17:29:11 【问题描述】:

我正在尝试通过套接字发送 proto,但出现分段错误。有人可以帮忙告诉我这个例子有什么问题吗?

文件.proto

message data  
    required string x1 = 1;
    required uint32 x2 = 2;
    required float x3 = 3;

xxx.cpp

    ...
    data data_snd, data_rec;

    //sending data to the server
    if (send(socket, &data_snd, sizeof(data_snd), 0) < 0) 
       cerr << "send() failed" ;
       exit(1);
       

     //receiving data from the client
     if (recv(socket, &data_rec, sizeof(data_rec), 0) < 0) 
        cerr << "recv() failed";
        exit(1);
       

感谢您的帮助和回复-

【问题讨论】:

【参考方案1】:

您不应该将 protobuf 对象本身写入套接字。使用SerializeXXX 系列方法获取可以写入套接字的字节序列。

std::string buf;
data.SerializeToString(&buf);
// now you can write buf.data() to the socket

【讨论】:

@jespere,非常感谢您的回复。只是一个问题。在接收时,我也应该反序列化吗?这是否类似于序列化?请帮助并再次感谢! 反序列化时,您使用 ParseFromString 方法(或其亲属之一)。 再次感谢!我终于成功了……请再问一个问题。您提到使用 buf.data()。它是否类似于 buf.c_str() ?对于要写入套接字的数据大小,我可以使用 sizeof(buf.data()) ...即 send(socket,buf.data(), sizeof(buf.data()), 0) 吗?再次感谢您的帮助 有关数据与 c_str 的描述,请参见此处。 cplusplus.com/reference/string/string/data【参考方案2】:

一方面,您假设对recv 的一次调用将检索所有数据。更重要的是,您没有通过序列化/反序列化代码 - 您只是从网络中读取并将字节直接放入对象中。您应该使用 Protocol Buffers 中基于流的 API 来写入和读取数据。

有关更多详细信息,请参阅Protocol Buffers C++ tutorial - 给出了保存到磁盘的示例,但我希望网络版本会相似,只是使用不同的流。

【讨论】:

@make:不,恐怕我没有足够的 C++ 经验来完成它的体面工作 - 但您应该能够轻松地调整教程中的代码。 飞碟,谢谢! ...这是我第一次尝试使用序列化/反序列化。任何帮助将不胜感激。再次感谢!【参考方案3】:

提供更多关于它的段错误以及如何管理服务器和客户端之间的连接的详细信息。

使用调试器并打印回溯,它会有所帮助...

【讨论】:

@make:不客气。答案并不能真正解释您的段错误。 recv 调用似乎是正确的,不应该按原样出现段错误。我怀疑你的代码比你的 sn-p 更复杂。祝你的应用好运。 感谢您的留言。实际上缺少序列化和反序列化代码,这就是我遇到分段错误的原因。在收到@jespere 的消息后,我成功地使我的代码正常工作。所以,谢谢大家,很高兴能和我分享你的经历......

以上是关于如何通过套接字发送.proto(协议缓冲区)中定义的类的主要内容,如果未能解决你的问题,请参考以下文章

如何在项目和团队之间共享和版本化协议缓冲区(proto)接口?

C ++中套接字上的协议缓冲区

反序列化缓冲区协议缓冲区

如何将已编译的协议缓冲区转换回 .proto 文件?

php socket 如何实现非阻塞

添加新消息后的 Proto2 编码/解码问题