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

时间:2011-02-12 11:25:42

标签: c# protocol-buffers protobuf-net

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

和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);

            }

1 个答案:

答案 0 :(得分:4)

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

首选项应该是Base128,它使用“varint”编码,因此较小的数字需要较少的空间来编码。此外,此前缀样式可用于使一系列对象与具有repeated字段的单个对象进行线程兼容,该字段具有一些有用的应用程序。

重新获得长度;如果您使用的是DeserializeWithLenghPrefixDeserializeItems ,则不需要 - 它会在内部处理它。但如果您需要,请查看Serializer.TryReadLengthPrefix

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

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