Java协议缓冲区 - 消息大小

时间:2013-08-29 05:44:06

标签: java protocol-buffers

因此,在过去的几周里,我一直在学习非常简单的网络编程和协议缓冲。现在,我有一个Java客户端和一个C#服务器,它们使用协议缓冲区来回通信。它一切正常,但为了使它在客户端(Java)端工作,我必须使用传入消息的确切大小创建我的字节数组,否则解析器将抛出错误的#34;协议消息包含无效标记(零)"

在做了一些研究之后,我发现我为DatagramPacket创建的数组(1024字节)有大量的尾随零(因为我从服务器传入的数据是27字节长),这就是为什么我现在如前所述,必须使用输入数据的确切大小创建数组。

至于问题,有没有办法找出我所有的原型"消息"在我的.proto文件中?如果没有某种静态getSize(),有没有办法可以通过"消息"中的字段类型来计算?

我现在正在使用的消息包含3个双打,现在我正在思考它,但我想知道一个知道发生了什么的人肯定的答案,是吗27因为每个双字节8字节,每个字节标记为1字节"在每个消息字段?

2 个答案:

答案 0 :(得分:0)

我相信你的问题在于你的套接字接收代码。具有尾随零的数组不是问题,但是在接收时应该检查接收的字节数(它是接收调用的返回值)并且仅考虑从开始到“接收的字节”的缓冲区数组的字节”

答案 1 :(得分:0)

protobuf数据中的根对象不是自终止的;它被设计为可附加的(附加=== merge),所以通常库只是读取,直到它用完数据。如果您有备用零,则无法解析下一个字段标题。有两种方法可以解决这个问题:

  • 如果您只想发送一条消息,只需关闭消息末尾的出站套接字即可;客户端应检测套接字的结束并相应地进行补偿(注意,除非使用长度受限的流包装,否则您仍然不想使用超大缓冲区)
  • 使用某种“框架”协议;最简单的方法是简单地在每条消息前面加上该消息中的字节数(注意,在一般情况下,这个大小不是固定的,但在3个双倍的情况下,每个都有一个字段标题的字段标题不大于16,然后是:它将是27个字节);然后,您可以创建正确大小的缓冲区(注意重复的数组分配可能很昂贵),或者更典型的是:使用长度有限的流包装器或内存支持的内存中流