如何使用 PrefixStyle 和 ProtoBuf-net 获得长度数?

Posted

技术标签:

【中文标题】如何使用 PrefixStyle 和 ProtoBuf-net 获得长度数?【英文标题】:How do i get the length number using PrefixStyle with ProtoBuf-net? 【发布时间】:2011-02-12 11:25:41 【问题描述】:

在下面的示例中,我如何使用 PrefixStyle 和 ProtoBuf-net 获取长度数?

PrefixStyle.Base128 和 PrefixStyle.Fixed32 有什么区别?

谢谢!

            PerfTest clone;
            using (MemoryStream ms = new MemoryStream())
            
                Serializer.SerializeWithLengthPrefix(ms, obj,PrefixStyle.Base128);
                byte[] raw = ms.ToArray();
                ms.Position = 0;
                clone = Serializer.DeserializeWithLengthPrefix<PerfTest>(ms,PrefixStyle.Base128);

            

编辑:使用下面的代码字节数组的长度为22,为什么TryReadLengthPrefix返回21?应该是返回22吧?

           PerfTest clone;
            using (MemoryStream ms = new MemoryStream())
            
                Serializer.SerializeWithLengthPrefix(ms, obj,PrefixStyle.Base128);
                byte[] raw = ms.ToArray();
                ms.Position = 0;

                int bArrayLen = ms.ToArray().Length; //returns 22

                int len;// set to 21. Why not 22?
                Serializer.TryReadLengthPrefix(ms, PrefixStyle.Base128,out len);

                clone = Serializer.DeserializeWithLengthPrefix<PerfTest>(ms,PrefixStyle.Fixed32);

            

【问题讨论】:

(添加了一段重新编辑) 我回来尝试调查 21/22,但如果没有可运行的示例,我就无法做到这一点 - 意思是:PerfTest 类型以及您用来创建 obj 的任何数据 【参考方案1】:

Fixed32 总是使用 4 个字节作为长度前缀——这对于手动打包消息的人来说似乎并不罕见(事实上,由于重复请求,我什至不得不在某些时候添加不同的字节序版本)。

虽然首选应该是 Base128,它使用“varint”编码,所以小数字占用更少的空间进行编码。此外,此前缀样式可用于使对象序列与具有repeated 字段的单个对象线兼容,这有一些有用的应用。

重新获取长度;如果你使用DeserializeWithLenghPrefixDeserializeItems 你不应该需要 - 它在内部处理它。但如果你需要这个,请查看Serializer.TryReadLengthPrefix

澄清一下:*WithLengthPrefix 方法的目的是允许在单个流中分离不同的对象/消息 - 最常见的是:网络套接字。这是必要的,因为协议本身假设整个流是单个消息,因此会一直尝试读取,直到流/套接字关闭。

关于 22 对 21 字节;那是因为长度前缀本身需要一些长度 :) 实际上如果数组是 22 我有点惊讶有效负载不是 20 - I 字节字段标题(使组合流本身成为有效的 protobuf 流),1 字节长度和 20 字节的有效载荷。我现在在手机上,所以我无法运行样本进行调查;不过,可以省略字段标头(可选) - 因此它可以是 1 字节长度,21 字节有效负载。我稍后再看。

【讨论】:

我正在使用 tcp 套接字通过线路发送字节 [],所以我需要长度来确定我是否收到了所有的味精。 @DrGraystone - 如果您使用 DeserializeWithLengthPrefix 它应该自动执行此操作;既限制读取的内容,又检查完全读取了正确的数量。 对不起......你能提供一个你上面所说的例子吗?这对我来说没有意义。谢谢 @DrGraystone - 你想澄清哪一点?另外 - TryReadLengthPrefix 是否有效?

以上是关于如何使用 PrefixStyle 和 ProtoBuf-net 获得长度数?的主要内容,如果未能解决你的问题,请参考以下文章

怎样把json转为protocol buffer

protobuf.net 和条件序列化

gRPC初体验

caffe源码阅读

Protobuf使用规范分享

用 Maven 实现一个 protobuf 的 Java 例子