我们使用 protobuf v.3 通过 HTTP 将消息从 C# 客户端传输到 Java 服务器。
消息原型如下所示:
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”。
对于字符串
“啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊”
其中包含 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 个或更少的符号组成 - 没有问题。