繁体   English   中英

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

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

对不起,但我想我要疯了。 我在 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;

这产生了这个 output

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

这在 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(); }

哪个产量

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

二进制数据是一样的。 我检查了我是否使用了正确版本的 proto 文件。 我有点不知所措。 任何帮助表示赞赏。

您要求从整个buffer中解析消息 - 我的猜测是buffer的长度超过 88 个字节。

我不记得parseFrom是否允许您指定要读取的最大数据量,但另一种选择是:

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

请注意,这仍然存在问题,您假设您可以在一次调用中读取 stream 中的所有数据read ,这绝不是一个好主意 - 但这是一个非常独立的问题。 如果您要在写入后关闭套接字,您当然可以从 Java 代码中的套接字InputStream中解析 stream。 如果您打算关闭 stream,我建议先将消息长度写入套接字(作为 32 位整数),然后您可以在 Java 中读取它,并准确读取正确数量的数据,知道什么时候你完了。

暂无
暂无

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

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