2013-08-29 148 views
0

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

经过一番研究,我发现我为DatagramPacket创建的数组(1024bytes)有大量的尾随零(因为我从服务器接收到的数据长度是27bytes),这就是为什么我现在,如前所述,必须创建具有确切大小的传入数据的阵列。

至于这个问题,有没有什么方法可以找到我的.proto文件中的所有“proto”消息的大小?如果没有某种静态的getSize(),有没有一种方法可以根据“消息”中的字段类型来计算?

我现在使用的信息包含3个双打,现在我正在考虑这个问题,但是我想知道发生了什么的人肯定会回答,是因为每个双8bytes,每个消息字段上每个“标签”1个字节?

+0

您可以发送发送协议缓冲区消息之前的长度。 –

回答

0

protobuf数据中的根对象不是自行终止的;它被设计成可追加的(追加===合并),所以通常库会直接读取,直到数据用完。如果您有零备份,它将无法解析下一个字段标题。有两种解决方法:

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

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