- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们使用 protobuf v.3 通过 HTTP 将消息从 C# 客户端传输到 Java 服务器。
消息原型(prototype)如下所示:
message CLIENT_MESSAGE {
string message = 1;
}
客户端和服务器都对字符串使用 UTF-8 字符编码。
当我们使用像“abc”这样的短字符串值时一切都很好,但是当我们尝试传输包含 198 个字符的字符串时,我们会发现一个异常:
com.google.protobuf.InvalidProtocolBufferException:
While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length.
我们尝试比较包含 protobuf 数据的偶数字节数组,但没有找到解决方案。对于“aaa”字符串字节数组以这个字节开头:
10 3 97 97 97
其中10是protobuf字段号,3是字符串长度,69 65 67是“aaa”。
对于字符串
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
其中包含 198 个字符,字节数组以此开头:
10 198 1 97 97 97....
其中10是protobuf字段号,198是字符串长度,1好像是字符串标识符,还是什么?
以及为什么 protobuf 无法解析此消息?
已经花了将近一天的时间来寻找解决这个问题的方法,感谢任何帮助。
更新:
我们从客户端和服务器都进行了转储,但奇怪的是 - 转储不同!
在发送到服务器之前从客户端转储 Protobuf:
00000000 0A C6 01 61 61 61 61 61 61 61 61 61 61 61 61 61 ·Æ·aaaaaaaaaaaaa
00000010 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000020 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000030 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000040 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000050 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000060 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000070 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000080 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00000090 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000A0 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000B0 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
000000C0 61 61 61 61 61 61 61 61 61 aaaaaaaaa
服务器接收的 Protobuf 转储:
0000: 0A EF BF BD 01 61 61 61 61 61 61 61 61 61 61 61 .....aaaaaaaaaaa
0010: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0020: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0030: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0040: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0050: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0060: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0070: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0080: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
0090: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00A0: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00B0: 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaaaaaaa
00C0: 61 61 61 61 61 61 61 61 61 61 61 aaaaaaaaaaa
如您所见,protobuf 数据头是不同的...这完全打破了我的想法,怎么会发生这种情况?
UPDATE2:我们进行了一项研究,发现这个问题只发生在长度超过 128 个符号的字符串上。如果字符串由 128 个或更少的符号组成 - 没有问题。
最佳答案
好吧,最后问题出在字符编码上——我们尝试将二进制 protobuf 数据转换为字符串。
如果您需要将二进制 protobuf 数据作为字符串传输 - 首先在客户端将其编码为 base64,然后在服务器上从 base64 解码。
感谢@Marc Gravell 的帮助
关于protocol-buffers - Protobuf InvalidProtocolBufferException 与一些字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50387660/
我期望 new Buffer(buffer.toString()) 始终是逐字节相等的。但是,我遇到的情况并非如此。 首先,这是一个真实的案例: var buf1 = new Buffer(32);
我有用于记录数据的 Protocol Buffer 。 message Message { required double val1 = 1; optional int val2 =
请注意以下简单程序(基于 protobuf-net 项目 v1 wiki 中的示例): using System.Collections.Generic; using System.Diagnosti
在 Protocol Buffer 中,有没有办法让消息包含嵌套消息的集合?例如,消息主管可能有一个员工集合以及主管的姓名和部门。 最佳答案 是的。您使用 repeated领域; message Em
我想知道 Protocol Buffer 在解析流时如何处理损坏的数据。有没有办法知道数据是否已损坏。 Protocol Buffer 是否提供任何内置的数据完整性检查机制? 谢谢, 最佳答案 没有任
Protocol Buffer 如何处理类型版本控制? 例如,当我需要随时间更改类型定义时?就像添加和删除字段一样。 最佳答案 Google 设计的 protobuf 对版本控制非常宽容: 意外数据要
我尝试阅读 Protobuf 文档,但无法想象它可以用于许多用例。我想知道一些实际的 Protocol Buffer 性能改进用例。 谢谢 最佳答案 Protocol buffers 是一个序列化库,
给定 Protocol Buffer 模式和一些数据, Protocol Buffer 序列化是否跨库和语言具有确定性? 基本上,无论使用什么库,我是否可以保证相同的数据总是以相同的方式(直到字节)序
我正在使用一个示例 UWP C++/CX 程序,该程序创建两个 UDP 网络通信线程,它们使用 Windows::Storage::Streams::DataWriter 相互发送数据。和 Windo
我正在使用以下代码 int lenSend = odl->ByteSize(); char* buf = (char *)malloc(lenSend); odl->SerializeToArray(
Protocol Buffer 文档警告说...... You should never add behaviour to the generated classes by inheriting fr
我有一个定义如下的原型(prototype)模式, message User { int64 id = 1; bool email_subscribed = 2; bool sms_
我试图了解 Protocol Buffer 编码方法,将消息转换为二进制(或十六进制)格式时,我无法理解嵌入消息的编码方式。 我猜可能和内存地址有关,但我找不到准确的关系。 这是我所做的。 第 1 步
我需要序列化和反序列化一系列与字节流之间的 Protocol Buffer 消息。有一些预先确定的消息类型。编码类型信息的推荐方法是什么,以便我的应用程序可以知道它应该读取哪种类型? 最佳答案 最常见
与GSON相比, Protocol Buffer (protobuf)的优缺点是什么? 在什么情况下,protobuf比GSON更合适? 对于一个非常笼统的问题,我感到抱歉。 最佳答案 json(通过
message Person { required Empid = 1 [default = 100]; required string name = 2 [default = "Raju"]
我正在研究一个小型设备,该设备具有相当大的一组配置参数(~100 KB),这些参数是从 PC 软件生成的。过去,我们将参数存储在二进制文件中并将它们加载到数据结构中。维护有点烦人(不同的语言,确保结构
来自Encoding - Protocol Buffers - Google Code上的“签名类型”: ZigZag encoding maps signed integers to unsigne
我正在使用 Protocol Buffer ,一切正常。除了我不明白的事实 - 为什么我需要 proto 中的编号标签文件 : message SearchRequest { required s
Protocol Buffer 的吸引人的功能之一是它允许您扩展消息定义,而不会破坏使用较旧定义的代码。对于枚举according to the documentation: a field with
我是一名优秀的程序员,十分优秀!