从天网序列化 protobuf 和在 C# 中序列化给出不同的字节

Posted

技术标签:

【中文标题】从天网序列化 protobuf 和在 C# 中序列化给出不同的字节【英文标题】:Serializing protobuf from skynet and Serializing in C# gives different bytes 【发布时间】:2021-09-20 15:45:42 【问题描述】:

我不负责,也不熟悉天网,但我确信它使用的是 Protobuf 版本 3.14.0,它应该使用 c 语言版本。 我负责从 Nuget 下载的 C#(unity3d) 端,Protobuf 版本 3.14.0。 这是.proto的一部分:

 syntax = "proto3";
    ...
message tookPoint 
    points point = 1;
    int32 mid = 2;
    int32 capital = 3; 

message points 
    int32 offset = 1; 
    repeated int32 color = 2; 
    int32 flag = 3;

当我发送 "point": "offset": 5097, "color": [ 7 ], "flag": 1 , "mid": 1, "capital": 1 到服务器,它记录 point=offset=5097, flag=1, color=5, mid=1, capital=1 我已经搜索了有关 C++ 和 lua 的答案,但它们对解决问题毫无用处。我需要更多帮助 T T。我花了 3 天以上的时间。 如何将正确的字节发送到服务器 T T ?谢谢~~


对于debug.point=offset=2204, flag=1, color=8, mid=1, capital=1,服务器reuslt是10 01 18 10 0A 07 10 08 08 9c 11 18 01.C#结果是0A 08 08 9C 11 12 01 08 18 01 10 01 18 10。它们都可以在C#中正确反序列化。


天网protobuf版本为libprotoc 3.14.0

【问题讨论】:

Protobuf 可以以多种方式表示相同的数据 - 在最基本的级别:通过不同的字段顺序,考虑到示例中移动的“10 01 18 10”,这很可能 - 但在其他方式也。不幸的是,在我修复损坏的 Azure 订阅问题 (protogen.marcgravell.com/decode) 时,我通常用来调查此问题的工具目前处于脱机状态。我有点在做“周末”的事情,但如果你在星期一仍然被困并且没有解决方案,那么我几乎肯定可以提供帮助(当我在电脑前时)。 你的意思好像是说protobuf有一定的功能可以保证在不同平台下序列化成同一个字节串? 不,我的意思恰恰相反;我的意思是在任何平台上都没有一个正确的字节集 - 然而,有一些 conventions 通常但并不总是被遵循 - 这意味着输出通常看起来相同 好吧,我接受不同平台上数据的不同字节码的现实。现在我想了解一下示例协议,你的平台反序列化的结果是Color=5还是Color=7?有什么办法可以确保客户端和服务器是一致的?非常感谢@@ 周一还在我的名单上;不忽略你 - 只是:周末 【参考方案1】:

我已经找到了问题的原因和解决方案。 Protobuf 的 C# 类库默认将重复对象全部打包,而 libprotoc 3.14.0 在配置之前仍然按照之前的编码方案进行解码。因此,libprotoc 3.14.0 无法解码正确的结果。解决办法是配置libprotoc 3.14。

【讨论】:

以上是关于从天网序列化 protobuf 和在 C# 中序列化给出不同的字节的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 protobuf 在 C# 中序列化字典?

使用 Protobuf 和内存映射文件 C# 的 IPC

通讯协议及Google.Protobuf生成c#代码 序列及反序列化

C#中使用ProtoBuf提高序列化速度对比二进制序列化

protobuf-net 不使用私有设置器序列化 C# 属性

通过 C# 和 Java 之间的 protobuf-net 进行序列化/解封