Protocol buffers Protobuf net StackOverflow派生类型异常

Protocol buffers Protobuf net StackOverflow派生类型异常,protocol-buffers,protobuf-net,Protocol Buffers,Protobuf Net,我试图用protobuf net在一个通道上发送混合消息类型。我将以下来自不同来源的示例放在一起,它在第一次反序列化时抛出StackOverflow异常 我这样做对吗 FWIW它创建的文件的十六进制内容是“A2 06 02 08 08 01 AA 06 02 08 04 03” 谢谢,格雷格 [ProtoContract(ImplicitFields = ImplicitFields.AllFields)] [ProtoInclude(100, typeof(Derived1))] [Proto

我试图用protobuf net在一个通道上发送混合消息类型。我将以下来自不同来源的示例放在一起,它在第一次反序列化时抛出StackOverflow异常

我这样做对吗

FWIW它创建的文件的十六进制内容是“A2 06 02 08 08 01 AA 06 02 08 04 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();
    }
}
[协议(ImplicitFields=ImplicitFields.AllFields)]
[ProtoInclude(100,typeof(Derived1))]
[ProtoInclude(101,typeof(Derived2))]
公共类基类{public int Old;}
[协议(ImplicitFields=ImplicitFields.AllFields)]
公共类Derived1:Base{public int New1;}
[协议(ImplicitFields=ImplicitFields.AllFields)]
公共类Derived2:Base{public int New2;}
班级计划
{
静态void Main(字符串[]参数)
{
Base b1=new-Derived1(){Old=1,New1=2};
基b2=new-Derived2(){Old=3,New2=4};
使用(var fs=File.Create(@“C:\test.bin”))
{
Serializer.Serialize(fs,b1);
Serializer.Serialize(fs,b2);
}
基msg3、msg4;
使用(var fs=File.OpenRead(@“C:\test.bin”))
{
msg3=序列化程序。反序列化(fs);
msg4=序列化程序。反序列化(fs);
}
Console.WriteLine(((Derived1)msg3.New1);
Console.WriteLine(((Derived2)msg4.New2);
Console.ReadLine();
}
}

我想这里的问题是框架;protobuf(格式,而不是库)是由google设计为可追加的,其中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);
}
使用(var fs=File.Create(@“test.bin”))
{
Serializer.SerializeWithLengthPrefix(fs,b1,PrefixStyle.Base128,1);
Serializer.SerializeWithLengthPrefix(fs,b2,PrefixStyle.Base128,1);
}
基msg3、msg4;
使用(var fs=File.OpenRead(@“test.bin”))
{
msg3=序列化程序.DeserializeWithLengthPrefix(fs,PrefixStyle.Base128,1);
msg4=Serializer.DeserializeWithLengthPrefix(fs,PrefixStyle.Base128,1);
}

我在反序列化时遇到了同样的问题,v2.1.0-alpha-1版解决了这个问题

问候,

普鲁克