使用Protobuf网络发送二进制数据

本文关键字:二进制 数据 Protobuf 网络 使用 | 更新日期: 2023-09-27 18:00:43

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

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

当试图反序列化消息时,我捕捉到Protobuf-net:引发的异常

16:52:59.902:(007):[Error]StartReceiveLoop()中的内部异常:消息:试图读取超过流的末尾。堆栈跟踪:在ProtoBuf.ProtoReader.确保(Int32计数,严格布尔值)在c:''Dev''ProtoBuf net''protobof net''ProtoReader.cs:line 257中位于c:''Dev''ProtoBuf net''protobof net''ProtoReader.cs:line 921中的ProtoBuf.ProtoReader.AppendBytes(Byte[]值,ProtoReader阅读器)在proto_4(对象,ProtoReader)位于ProtoBuf.Serializer.CompiledSerializer.ProtoBuf.serializer.IProtoSerializer.Read(对象值,ProtoReader源),位于c:''Dev''ProtoBuf net''protobf net''Serializers''CompiledSerilizer.cs:line 57在c:''Dev''ProtoBuf net''protobof net''Meta''RuntimeTypeModel.cs:line 775中的ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32键,对象值,ProtoReader源)位于c:''Dev''ProtoBuf net''protobof net''Meta''TypeModel.cs:line 700中的ProtoBuf.Meta.TypeModel.DescializeCore(ProtoReader读取器,类型类型,对象值,布尔noAutoCreate)在c:''Dev''ProtoBuf-net''protobaf-net''Meta''TypeModel.cs:line 588中的ProtoBuf.Meta.TypeModel.Descialize(流源、对象值、类型类型、序列化上下文上下文)位于ProtoBuf.Serialize.Deserialize[T](流源),位于c:''Dev''ProtoBuf-net''protobf-net''Serializer.cs:line 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);
        }
    }
}

}

使用Protobuf网络发送二进制数据

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