Kon*_*che 5 c++ java sockets tcp protocol-buffers
我现在使用protobuf有几个星期了,但是在Java中解析 protobuf 消息时仍然不断遇到异常。
我使用C++创建 protobuf 消息,并使用boost 套接字将它们发送到 Java 客户端正在侦听的服务器套接字。传输消息的C++代码是这样的:
boost::asio::streambuf b;
std::ostream os(&b);
ZeroCopyOutputStream *raw_output = new OstreamOutputStream(&os);
CodedOutputStream *coded_output = new CodedOutputStream(raw_output);
coded_output->WriteVarint32(agentMessage.ByteSize());
agentMessage.SerializeToCodedStream(coded_output);
delete coded_output;
delete raw_output;
boost::system::error_code ignored_error;
boost::asio::async_write(socket, b.data(), boost::bind(
&MessageService::handle_write, this,
boost::asio::placeholders::error));
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,我写的是WriteVarint32消息的长度,因此 Java 端应该通过使用parseDelimitedFrom它应该读取多远来知道:
AgentMessage agentMessage = AgentMessageProtos.AgentMessage
.parseDelimitedFrom(socket.getInputStream());
Run Code Online (Sandbox Code Playgroud)
但这没有帮助,我不断收到这些异常:
Protocol message contained an invalid tag (zero).
Message missing required fields: ...
Protocol message tag had invalid wire type.
Protocol message end-group tag did not match expected tag.
While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either than the input has been truncated or that an embedded message misreported its own length.
Run Code Online (Sandbox Code Playgroud)
重要的是要知道,并不是每条消息都会引发这些异常。这只是我收到的最多的消息的一小部分,效果很好 - 但我仍然想解决这个问题,因为我不想忽略这些消息。
如果有人可以帮助我或使用他的想法,我将非常感激。
另一个有趣的事实是我收到的消息数量。我的程序通常在 2 秒内收到 1.000 条消息。20 秒内大约 100.000 个,依此类推。我人为减少了发送的消息,当只发送6-8条消息时,根本没有错误。那么这可能是 Java 客户端套接字端的缓冲问题吗?
假设有 60,000 条消息,其中平均有 5 条被损坏。
我不熟悉Java API,但我想知道Java如何处理表示消息长度的uint32值,因为Java只有带符号的32位整数。快速查看 Java API 参考告诉我,无符号 32 位值存储在有符号 32 位变量中。那么如何处理用无符号 32 位值表示消息长度的情况呢?另外,Java 实现中似乎支持 varint 有符号整数。它们被称为 ZigZag32/64。AFAIK,C++ 版本不知道这种编码。那么您的问题的原因可能与这些事情有关吗?
| 归档时间: |
|
| 查看次数: |
5655 次 |
| 最近记录: |