如何使用 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
字段的单个对象线兼容,这有一些有用的应用。
重新获取长度;如果你使用DeserializeWithLenghPrefix
或DeserializeItems
你不应该需要 - 它在内部处理它。但如果你需要这个,请查看Serializer.TryReadLengthPrefix
。
澄清一下:*WithLengthPrefix
方法的目的是允许在单个流中分离不同的对象/消息 - 最常见的是:网络套接字。这是必要的,因为协议本身假设整个流是单个消息,因此会一直尝试读取,直到流/套接字关闭。
关于 22 对 21 字节;那是因为长度前缀本身需要一些长度 :) 实际上如果数组是 22 我有点惊讶有效负载不是 20 - I 字节字段标题(使组合流本身成为有效的 protobuf 流),1 字节长度和 20 字节的有效载荷。我现在在手机上,所以我无法运行样本进行调查;不过,可以省略字段标头(可选) - 因此它可以是 1 字节长度,21 字节有效负载。我稍后再看。
【讨论】:
我正在使用 tcp 套接字通过线路发送字节 [],所以我需要长度来确定我是否收到了所有的味精。 @DrGraystone - 如果您使用 DeserializeWithLengthPrefix 它应该自动执行此操作;既限制读取的内容,又检查完全读取了正确的数量。 对不起......你能提供一个你上面所说的例子吗?这对我来说没有意义。谢谢 @DrGraystone - 你想澄清哪一点?另外 - TryReadLengthPrefix 是否有效?以上是关于如何使用 PrefixStyle 和 ProtoBuf-net 获得长度数?的主要内容,如果未能解决你的问题,请参考以下文章