【发布时间】:2017-11-05 20:12:13
【问题描述】:
当我使用 protobuf 从 c# 向 Golang 发送字节数据包时没有问题。但是当我从 Golang 向 c# 发送一个字节时会出错。
我在c#中使用这段代码来获取golang发送的protobuf:
Stream stream = new MemoryStream(m);
PRSData data;
data = PRSData.Parser.ParseFrom(stream);
print(data);
然后我在 c# 中得到这个错误:
InvalidProtocolBufferException:协议消息包含无效 标签(零)。 Google.Protobuf.CodedInputStream.ReadTag ()
c#生成的protobuf的结构也是对的,golang的不正确
c#生成的protobuf结构为:
{ "action": "move", "id": "player_361", "room": "SyONuNo0W", "pos": { "x": 74.423, "y": -0.04, "z": 10.903 } }
golang生成的protobuf结构为:
action:"move" id:"player_361" room:"SyONuNo0W" pos:<x:74.423 y:-0.04 z:10.903 >
请帮助我使用 c# 和 Golang 中的 protobuf 以及它们之间的真正转换。
【问题讨论】:
-
您使用的是二进制布局吗?还是json布局?听起来像二进制,但底部的示例是 json。数据是否意外填充?如果它是二进制的,它在protogen.marcgravell.com/decode 上可以正常工作吗? (您可以使用该页面来验证来自文件、十六进制或 base-64 的二进制文件) - 请注意我的预感是在有效负载之后进行填充
-
我从c#
PRSData data = ... portobyf ; byte[] buf = ((Imessage)data).ToByteArray();发送这样的数据 -
太棒了;现在,如果您使用 hex、base-64 或文件版本并通过 /decode 运行它,它会告诉您数据是否格式错误。首先要了解它是否是畸形的。但是,在您的 golang 代码中,您如何获得
m并不明显,而在 c# 代码中,您对buf所做的操作并不明显,因此您完全有可能在传输过程中意外填充.哎呀,你可以做一个非常简单的测试:比较buf的长度和m的长度。如果它们不一样:修复它。然后检查内容。 -
最终,直到您检查是否收到了正确的数据(即
m和buf包含完全相同的字节),所有的赌注都被取消了。 -
是的,你是对的。 c# 中的字节长度为 1024,但在 golang 中为 56。在下面的代码中,变量 size 为 56 字节,但在这一行 m = (byte[])ar.AsyncState; 变为 1024 字节 ' int size = sckCommunication.EndReceiveFrom(ar, ref epRemote); if (size > 0) { // 用来帮助我们获取数据 byte[] m = new byte[numberBytes]; // 获取数据 m = (byte[])ar.AsyncState; } `
标签: c# go protocol-buffers