使用Protobuf-net

时间:2015-07-01 14:59:43

标签: c# .net serialization protocol-buffers protobuf-net

使用Protobuf-net发送二进制数组时是否有任何特殊要求?我有一个消息类,它包含一些二进制数据:

[ProtoContract]
public class BitmapPackage : BaseMessage
{
    [ProtoMember(1)]
    public byte[] BitmapData;
}

当尝试反序列化消息时,我捕获了Protobuf-net抛出的异常:

  

16:52:59.902:(007):[错误] StartReceiveLoop()中的内部异常:消息:尝试读取流的末尾.Stack跟踪:在ProtoBuf.ProtoReader.Ensure(Int32计数,布尔值严格) )在c:\ Dev \ protobuf-net \ protobuf-net \ ProtoReader.cs:第257行      at ProtoBuf.ProtoReader.AppendBytes(Byte [] value,ProtoReader reader)in c:\ Dev \ protobuf-net \ protobuf-net \ ProtoReader.cs:line 921      在proto_4(Object,ProtoReader)      at ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value,ProtoReader source)in c:\ Dev \ protobuf-net \ protobuf-net \ Serializers \ CompiledSerializer.cs:第57行      at ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key,Object value,ProtoReader source)in c:\ Dev \ protobuf-net \ protobuf-net \ Meta \ RuntimeTypeModel.cs:line 775      at ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader,Type type,Object value,Boolean noAutoCreate)in c:\ Dev \ protobuf-net \ protobuf-net \ Meta \ TypeModel.cs:line 700      at ProtoBuf.Meta.TypeModel.Deserialize(流源,对象值,类型类型,SerializationContext上下文)在c:\ Dev \ protobuf-net \ protobuf-net \ Meta \ TypeModel.cs:第588行      在ProtoBuf.Serializer.Deserialize [T](流源)c:\ Dev \ protobuf-net \ protobuf-net \ Serializer.cs:第77行

仅在发送一个特定位图时才会发生这种情况。所以我的问题是,在使用protobuf-net对其进行反序列化之前,我应该以某种方式“逃避”二进制数据吗?

更新: 以下是正在接收的代码:

private async Task StartReceiveLoop()
{
await Task.Yield();

while(!_readOpCancelToken.IsCancellationRequested)
{
    try
    {
        var buffer = new byte[4096];
        int bytesRx = await _pipe.ReadAsync(
            buffer, 0, buffer.Length, _readOpCancelToken);

        Logger.LogInfo("Pipe connection: Got " + bytesRx + " bytes");

        if (bytesRx == 0) break;
        if (_readOpCancelToken.IsCancellationRequested) break;

        await _receivedDataStream.WriteAsync(buffer, 0, bytesRx);

        if (_pipe.IsMessageComplete)
        {
            // Get out the routing data
            _receivedDataStream.Position = 0;
            byte[] intbuffer = new byte[4];

            _receivedDataStream.Read(intbuffer, 0, 4);
            int size = BitConverter.ToInt32(intbuffer, 0);

            _receivedDataStream.Read(intbuffer, 0, 4);
            int typeId = BitConverter.ToInt32(intbuffer, 0);

            _receivedDataStream.Read(intbuffer, 0, 4);
            int routeTag = BitConverter.ToInt32(intbuffer, 0);

            messageObj = messageObj = Serializer.NonGeneric.Deserialize(messageType, _receivedDataStream);

            // Process message on UI thread via tick queue
            TickSystem.OneTimeTickQueue.Enqueue(new Action(() =>
            {
                ProcessMessageExtApp.ProcessThisMessage(messageObj);
            }));

            // Reset the stream
            _receivedDataStream = new MemoryStream();
        }
    }
    catch (Exception e)
    {
        Logger.LogError(
            "Exception in StartReceiveLoop():" +
            "Message: " + e.Message +
            "Stack Trace: " + e.StackTrace);

        if (e.InnerException != null)
        {
            Logger.LogError(
            "Inner Exception in StartReceiveLoop():" +
            "Message: " + e.InnerException.Message +
            "Stack Trace: " + e.InnerException.StackTrace);
        }
    }
}

}

1 个答案:

答案 0 :(得分:1)

实际问题不是Protobuf-net,而是IsMessageComplete过早发出信号的事实。修复是使用字节数组写入管道服务器上的管道而不是流复制并在完成每个数据包后刷新管道。