protocol-buffers - Protobuf-net StackOverflow 派生类型异常

标签 protocol-buffers protobuf-net

我正在尝试使用 protobuf-net 在单个 channel 上发送混合消息类型。我将以下来自各种来源的示例放在一起,它在第一次反序列化时引发 StackOverflow 异常。

我的处理方式正确吗?

FWIW它创建的文件的十六进制内容是“A2 06 02 08 02 08 01 AA 06 02 08 04 08 03”

谢谢,格雷格

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
[ProtoInclude(100, typeof(Derived1))]
[ProtoInclude(101, typeof(Derived2))]
public class Base { public int Old; }

[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class Derived1 : Base { public int New1; }
[ProtoContract(ImplicitFields = ImplicitFields.AllFields)]
public class Derived2 : Base { public int New2; }  

class Program
{
    static void Main(string[] args)
    {

        Base b1 = new Derived1() { Old = 1, New1 = 2 };
        Base b2 = new Derived2() { Old = 3, New2 = 4 };

        using (var fs = File.Create(@"C:\test.bin"))
        {
            Serializer.Serialize(fs, b1);
            Serializer.Serialize(fs, b2);
        }

        Base msg3, msg4;
        using (var fs = File.OpenRead(@"C:\test.bin"))
        {
            msg3 = Serializer.Deserialize<Base>(fs);  
            msg4 = Serializer.Deserialize<Base>(fs);
        }

        Console.WriteLine(((Derived1)msg3).New1);
        Console.WriteLine(((Derived2)msg4).New2);
        Console.ReadLine();
    }
}

最佳答案

我认为这里的问题是框架; protobuf(格式,而不是库)由谷歌设计为可追加的,其中append===merge。如果序列化消息 A,然后立即序列化消息 B,然后反序列化整个消息:您会得到一条消息,而不是两条。显然,这很可能导致意外结果、错误解释的数据和错误。

那么,诀窍就是对消息进行构建,以便您可以单独处理它们。幸运的是,protobuf-net 正是为此目的提供了 SerializeWithLengthPrefix 和 DeserializeWithLengthPrefix 方法。在序列化期间,这会在每条消息前面添加一个标记,以指示后续数据的长度。在反序列化期间,首先读取长度前缀,从而允许为每条消息消耗正确的数据量。

支持多种布局和长度前缀样式;最重要的是它们在序列化和反序列化步骤之间匹配。如果您希望数据是“纯 protobuf”(即可解析为另一个平台上外部消息上的重复字段),那么“base-128,字段 1”是一个不错的选择。

这工作正常:

using (var fs = File.Create(@"test.bin"))
{
    Serializer.SerializeWithLengthPrefix(fs, b1, PrefixStyle.Base128, 1);
    Serializer.SerializeWithLengthPrefix(fs, b2, PrefixStyle.Base128, 1);
}

Base msg3, msg4;
using (var fs = File.OpenRead(@"test.bin"))
{
    msg3 = Serializer.DeserializeWithLengthPrefix<Base>(fs, PrefixStyle.Base128, 1);
    msg4 = Serializer.DeserializeWithLengthPrefix<Base>(fs, PrefixStyle.Base128, 1);
}

关于protocol-buffers - Protobuf-net StackOverflow 派生类型异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29424197/

相关文章:

json - Flatbuffer 与 CBOR

python - 导入caffe导致ImportError : "No module named google.protobuf.internal" (import enum_type_wrapper)

protocol-buffers - Apache Thrift 和 Google Protocol Buffer 有什么用途?

c# - Protobuf-net r282 在反序列化使用 r249 序列化的对象时出现问题

java - Protocol Buffer java 源代码中 Unresolved 依赖项

c++ - google protobuf 编译器不为服务标签生成类?

c# - protobuf-net 从 child 到 parent 的继承

c# - protobuf-net 隐式合约

c# - 在不标记成员的情况下使用 ProtoBuf.NET 进行序列化

.net - C# : How Are Boxed Value Types Handled 中的 Protocol Buffer