简体   繁体   English

谷歌协议缓冲区 - 在 C++ 中编码,在 Java 中解码 - InvalidProtocolBufferException

[英]google protocol buffers - encode in C++, decode in Java - InvalidProtocolBufferException

Sorry, but I think I am going mad.对不起,但我想我要疯了。 I have this in C++:我在 C++ 中有这个:

std::stringstream message;
protoMsg.SerializeToOstream(&message);
boost::system::error_code ignored_error;
std::cout << "Writing response to socket. Byte size " << protoMsg.ByteSize() << " Buffer " << message.str().length() << std::endl;
for(int i(0);i<(int)message.str().length();i++)
    std::cout << (int)message.str().at(i);
std::cout << std::endl;
boost::asio::write(socket, boost::asio::buffer(message.str()), ignored_error);
std::cout << "Done writing." << std::endl;

Which yields this output这产生了这个 output

Writing response to socket. Byte size 88 Buffer 88
1886811891161111001113278971091012500000000320400480560640730000000081000000008859621061211611110011132115121109789710910111416691201161011141109710832114101113117101115116
Done writing.

And this in Java:这在 Java 中:

try {
  System.out.println("Parsing");
  int lenbytes = is.read(buffer);
  System.out.println("Read bytes " + lenbytes);
  for(int i=0;i<lenbytes;i++)
    System.out.print(Integer.toString((int)buffer[i]));
  System.out.println("");
  EnvInfoProto envInfoProto = EnvInfoProto.parseFrom(buffer);
  System.out.println("Done");
  return envInfoProto;
} catch(IOException ignore) { System.out.println("Ex: " + ignore.toString(); }

Which yields哪个产量

Parsing
Read bytes 88
1886811891161111001113278971091012500000000320400480560640730000000081000000008859621061211611110011132115121109789710910111416691201161011141109710832114101113117101115116
Ex: com.google.protobuf.InvalidProtocolBufferException: Protocol message contained an invalid tag (zero).

The binary data is the same.二进制数据是一样的。 I checked that I am using the right version of the proto files.我检查了我是否使用了正确版本的 proto 文件。 I am a bit at a loss tbh.我有点不知所措。 Any help appreciated.任何帮助表示赞赏。

You're asking the message to be parsed from the whole of buffer - and my guess is that buffer is more than 88 bytes long.您要求从整个buffer中解析消息 - 我的猜测是buffer的长度超过 88 个字节。

I can't remember offhand whether parseFrom allows you to specify the maximum amount of data to read, but an alternative would be:我不记得parseFrom是否允许您指定要读取的最大数据量,但另一种选择是:

ByteArrayIntputStream stream = new ByteArrayInputStream(buffer, 0, lenbytes);
EnvInfoProto envInfoProto = EnvInfoProto.parseFrom(stream);

Note that this still has the problem that you're assuming you can read all the data from the stream in a single call to read , which is never a good idea - but that's a very separate issue.请注意,这仍然存在问题,您假设您可以在一次调用中读取 stream 中的所有数据read ,这绝不是一个好主意 - 但这是一个非常独立的问题。 If you're going to close the socket after writing, you could just parse stream from the socket's InputStream in the Java code, of course.如果您要在写入后关闭套接字,您当然可以从 Java 代码中的套接字InputStream中解析 stream。 If you're not going to close the stream, I would suggest writing the message length to the socket first (as a 32-bit integer) so you can then read that in Java, and read exactly the right amount of data, knowing when you're finished.如果您打算关闭 stream,我建议先将消息长度写入套接字(作为 32 位整数),然后您可以在 Java 中读取它,并准确读取正确数量的数据,知道什么时候你完了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM