在使用长度前缀反序列化之前读取长度前缀
Read length prefix before deserialize with length prefix
protobuf-net 中是否有任何方法可以从流中读取数据包长度,然后使用 Serializer.DeserializeWithLengthPrefix
反序列化数据包?我的意思是在不将数据复制到其他流等的情况下执行这些操作
这在很大程度上取决于您 "read packet length from stream" 的意思。首先,数据包 在流中不存在 - 你只有:流。您可以在其中 frame,而这正是 *WithLengthPrefix
方法 已经做的 。因此,如果您在两端使用 *WithLengthPrefix
方法,它应该已经正确读取而不会试图过度读取等。但是,问题中没有足够的信息可以说更多。
来自评论中的澄清;是的,您可以使用 Serializer.TryReadLengthPrefix
手动读取前缀 - 然后创建一个长度受限的 reader;如果它是类似这样的同步代码:
while(Serializer.TryReadLengthPrefix(stream, style, out length))
{
using(var reader = new ProtoReader(stream, model, ctx, length))
{
var obj = mode.Deserialize(reader, null, type);
// ...
}
}
但是,在异步 IO 中,代码变得 多 复杂;首先你需要缓冲直到你知道你有足够的帧头;那么您需要继续读取和缓冲,直到获得该帧的数据。您的基本异步循环将更像是:
EndRead() {
AppendNewData();
bool consumed = false;
while(HaveFrameHeaderInBuffer() && HavePayloadInBuffer()) {
ProcessFrame();
consumed = true;
}
if(consumed) DiscardConsumedDataAndShiftLeftoverUnusedData();
BeginRead();
}
protobuf-net 中是否有任何方法可以从流中读取数据包长度,然后使用 Serializer.DeserializeWithLengthPrefix
反序列化数据包?我的意思是在不将数据复制到其他流等的情况下执行这些操作
这在很大程度上取决于您 "read packet length from stream" 的意思。首先,数据包 在流中不存在 - 你只有:流。您可以在其中 frame,而这正是 *WithLengthPrefix
方法 已经做的 。因此,如果您在两端使用 *WithLengthPrefix
方法,它应该已经正确读取而不会试图过度读取等。但是,问题中没有足够的信息可以说更多。
来自评论中的澄清;是的,您可以使用 Serializer.TryReadLengthPrefix
手动读取前缀 - 然后创建一个长度受限的 reader;如果它是类似这样的同步代码:
while(Serializer.TryReadLengthPrefix(stream, style, out length))
{
using(var reader = new ProtoReader(stream, model, ctx, length))
{
var obj = mode.Deserialize(reader, null, type);
// ...
}
}
但是,在异步 IO 中,代码变得 多 复杂;首先你需要缓冲直到你知道你有足够的帧头;那么您需要继续读取和缓冲,直到获得该帧的数据。您的基本异步循环将更像是:
EndRead() {
AppendNewData();
bool consumed = false;
while(HaveFrameHeaderInBuffer() && HavePayloadInBuffer()) {
ProcessFrame();
consumed = true;
}
if(consumed) DiscardConsumedDataAndShiftLeftoverUnusedData();
BeginRead();
}