【问题标题】:Sending binary data with Protobuf-net使用 Protobuf-net 发送二进制数据
【发布时间】:2015-09-18 19:47:07
【问题描述】:

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

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

在尝试反序列化消息时,我捕获了 Protobuf-net 引发的异常:

16:52:59.902: (007): [Error] Inner Exception in StartReceiveLoop():Message: Attempted to read over the end of the stream.Stack Trace: at ProtoBuf.ProtoReader.Ensure(Int32 count, Boolean strict ) 在 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 257 在 c:\Dev\protobuf-net\protobuf-net\ProtoReader.cs:line 921 中的 ProtoBuf.ProtoReader.AppendBytes(Byte[] value, ProtoReader reader) 在 proto_4(对象,ProtoReader) 在 ProtoBuf.Serializers.CompiledSerializer.ProtoBuf.Serializers.IProtoSerializer.Read(Object value, ProtoReader source) in c:\Dev\protobuf-net\protobuf-net\Serializers\CompiledSerializer.cs:line 57 在 c:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 775 中的 ProtoBuf.Meta.RuntimeTypeModel.Deserialize(Int32 key, Object value, ProtoReader source) 在 c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 700 中的 ProtoBuf.Meta.TypeModel.DeserializeCore(ProtoReader reader, Type type, Object value, Boolean noAutoCreate) 在 c:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 588 中的 ProtoBuf.Meta.TypeModel.Deserialize(Stream source, Object value, Type type, SerializationContext context) 在 ProtoBuf.Serializer.Deserialize[T](Stream source) in c:\Dev\protobuf-net\protobuf-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);
        }
    }
}

}

【问题讨论】:

  • 你的接收逻辑坏了,这不是protofuf的错。您正在传递不完整的数据。不知道你说的逃避是什么意思。发布负责将数据交给 protobuf 的代码。可能您也应该修复您的日志记录,因为似乎缺少错误详细信息。最好记录完整的异常 ToString。
  • 看起来不错。例外情况如何?处理中断,因为如果出现错误,您将永远继续循环。也发布发送代码,因为我无法发现读取代码的问题。

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


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2017-01-27
    • 2016-03-07
    相关资源
    最近更新 更多