繁体   English   中英

C#Protobuf-net:如何从网络流中连续反序列化?

[英]C# Protobuf-net: how do I deserialize consecutively from a network stream?

我(非常感谢)使用Marc Gravell的出色的Protobuf-net协议缓冲区库。 不幸的是,我不够智能,无法理解反序列化通过电线插入的对象的正确方法。

作为我努力的基础,我遵循以下问题的建议:

使用protobuf-net对序列化的数据进行反序列化(protocolBuffer)
protobuf:到/从套接字连续序列化和反序列化

我在整个会话期间(几分钟,几小时...谁知道?)保持TCP连接打开,并使用一个只要连接一直持续的单个网络流。 我正在通过此流接收许多PB消息。

鉴于我使用的是“ TryDeserializeWithLengthPrefix”,因此我期望该库能够对流进行排序,以便有足够的数据来解析整个对象。 但这似乎并非如此。

我写了一个简单的测试:

    [Test]
    public void DeserializeSimpleObjectInParts ()
    {
        SimpleObject origin = new SimpleObject();
        byte[] wholeObj = ProtobufSerializer.SerializeToByteArray ( origin );
        int length = wholeObj.Length;
        int midpoint = length / 2;
        int sizeA = midpoint;
        int sizeB = length - midpoint;
        byte[] aaa = new byte[sizeA];
        byte[] bbb = new byte[sizeB];
        for ( int i = 0; i < midpoint; i++ )
        {
            aaa [ i ] = wholeObj [ i ];
        }
        for ( int j = midpoint; j < length; j++ )
        {
            bbb [ j - midpoint ] = wholeObj [ j ];
        }

        using ( MemoryStream streamA = new MemoryStream ( aaa ) )
        {
            using ( MemoryStream streamB = new MemoryStream ( bbb ) )
            {
                streamA.Position = 0;
                streamB.Position = 0;
                Debug.LogDebug ( "streamA.Length = " + streamA.Length + ", streamB.Length = " + streamB.Length );

                object resultA = null;
                bool succeededA = false;
                try {
                    succeededA = ProtobufSerializer.Deserialize ( streamA, out resultA );
                }
                catch ( Exception e )
                {
                    Debug.LogDebug ( "Exception = " + e );
                    Debug.LogDebug ( "streamA.Position = " + streamA.Position + ", streamA.Length = " + streamA.Length );
                }
            }
        }
    }

请注意,在上面,“ ProtobufSerializer.Deserialize”仅仅是通过我自己的服务类直接调用“ TryDeserializeWithLengthPrefix”的调用。 类型编码业务在那里。

当我运行此测试时,将引发以下异常:

System.IO.EndOfStreamException: Failed to read past end of stream.

来自Google朋友的建议表明,我有责任查看套接字代码中的长度前缀。 但这有什么帮助? C#网络流没有供我比较的Length属性。

我真的需要做一个中间步骤,在流上运行一个循环,构建正确大小的字节数组,然后从它们中产生新的流,然后将它们传递到Protobuf-net吗? 这似乎是一种反模式,而且会打击性能。

我在这里想念什么?

鉴于我使用的是“ TryDeserializeWithLengthPrefix”,因此我期望该库能够对流进行排序,以便有足够的数据来解析整个对象。

没有可靠,有效的方法来对抽象Stream对象进行“分类等待”。

C#网络流没有供我比较的Length属性。

计算从套接字流写入缓冲区流的数据。 这将是您的“ Length”属性,用于与开始时获得的长度前缀进行比较。 一旦有了足够的数据,就将缓冲流找回前缀,然后将其传递给解串器以获取对象。 现在,再次查找缓冲流,并重新使用它以获取下一条消息。 重复。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM