套接字上的Protobuf-net序列化.找不到无参数的构造函数ProtoException [英] Protobuf-net serialization on sockets. No parameterless constructor found ProtoException

查看:30
本文介绍了套接字上的Protobuf-net序列化.找不到无参数的构造函数ProtoException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个使用套接字完成进程间通信的应用程序.当客户端与我创建的服务器连接并发送序列化消息时,该过程开始.此消息,我使用Protobuf-net,使用SerializeWithLengthPrefix进行序列化,然后使用DeserializeWithLengthPrefix反序列化.客户端将消息发送到服务器,该服务器会对其进行完全反序列化,但是对于服务器到客户端而言,情况并非如此.

I have created an application where interprocess communication is done using sockets. The procedure starts when a client connects with the server that I created and sends a serialized message. This message, I serialize using Protobuf-net, using SerializeWithLengthPrefix and deserialize it using DeserializeWithLengthPrefix. The client sends messages to the server who deserializes it perfectly, but the same is not true in the case of server to client.

主类是BaseMessage,它是抽象的.

The main class is BaseMessage, which is abstract.

[Serializable, ProtoContract, ProtoInclude(5001, typeof(LogonMessage))]
abstract public class BaseMessage
{
    public BaseMessage()
    {

    }

    abstract public int MessageType { get; }
}

LogonMessage实现BaseMessage类.

And LogonMessage implements the BaseMessage Class.

[Serializable, ProtoContract]
public class LogonMessage : BaseMessage
{
    public LogonMessage()
    {

    }

    [ProtoMember(1)]
    public string Broker { get; set; }

    [ProtoMember(2)]
    public int ClientType { get; set; }

    public override int MessageType
    {
        get { return 1; }
    }
}

在最初的握手之后,客户端请求一些在protobuf-net的帮助下序列化的服务,而我端的本地服务器通过从Web上的另一台服务器请求数据来服务该服务.从客户端到服务器的这种消息传输是完美完成的.

After the initial handshake, the client requests some service serialized with the help of protobuf-net and the local server at my end serves it by requesting data from another server on the web. This message transfer from the client to the server is done flawlessly.

当我的服务器从Web服务器接收到数据时,它将对其进行序列化并将数据发送到客户端.但是这一次,当我尝试使用相同的过程在客户端反序列化数据时,出现以下异常:找不到BaseMessage的无参数构造函数"

When my server receives the data from the web server, it serializes it and sends the data to the client. But this time, when I try to deserialize the data on the client-side using the same procedure, I get the following exception: "No parameterless Constructor found for BaseMessage"

我使用下面的代码反序列化(这是发生异常的地方).

I deserialize using the following line of code(this is where the exception occurs).

BaseMessage baseMessage = Serializer.DeserializeWithLengthPrefix<BaseMessage>(networkStream, PrefixStyle.Base128);

这就是邮件在服务器上的序列化方式.

And this is how the message was serialized on the server.

Serializer.SerializeWithLengthPrefix(networkStream, baseMessage, PrefixStyle.Base128);

在客户端和服务器之间的连接开始时使用的NetworkStream存储在一个对象中,并且该对象存储在字典中.我从字典中的该对象中选择了相同的NetworkStream,并使用它来将序列化的数据(从服务器)发送到客户端.但是出现了上述问题.有帮助吗?

The NetworkStream used at the start of the connection between the client and server is stored in an object and that object is stored in a dictionary. I pick out the same NetworkStream from that object in the dictionary and use it to send serialized data to the client(from the server). But the above mentioned problem occurs. Any help?

预先感谢...

推荐答案

在任何v2版本中都应该可以正常工作;2.0.0.480是当前在NuGet上公告的下载,但2.0.0.580也可用.我已经检查了1.0.0.280和2.0.0.480,并且它们都没有显示此症状,所以我猜您正在使用其他版本.因此,我的建议是:确保您使用的是这两个之一(或更高,如果可用).

That should work fine in any v2 release; 2.0.0.480 is the currently advertised download on NuGet, but 2.0.0.580 is also available. I've checked both 1.0.0.280 and 2.0.0.480, and neither of them show this symptom, so I'm guessing you're using a different build. My advice, therefore, is: make sure you're on one of those two (or higher, where available).

有关信息,您不需要protobuf-net的 [Serializable] ,但这也不会造成伤害.另外,您的 BaseMessage 构造函数可能应该受到保护(( public abstract 类型).但是由于编译器会自动为您完成所有 操作,因此您可以简化以下操作:

For info, you don't need [Serializable] for protobuf-net, but it doesn't hurt either. Also, your BaseMessage constructor should probably be protected (public doesn't really make sense on the constructor of an abstract type). But since the compiler does all that for you automatically, you can simplify:

[ProtoContract, ProtoInclude(5001, typeof(LogonMessage))]
abstract public class BaseMessage
{
    abstract public int MessageType { get; }
}


[ProtoContract]
public class LogonMessage : BaseMessage
{
    [ProtoMember(1)]
    public string Broker { get; set; }

    [ProtoMember(2)]
    public int ClientType { get; set; }

    public override int MessageType
    {
        get { return 1; }
    }
}

其他想法: 5001 有点偏高;您可以通过低价值的包含数获得更好的效率. 1 让我想到了.它们不必是通用唯一的:只需在该类型内唯一即可.

Other thoughts: 5001 is a bit on the high-side; you will get better efficiency from low-value include-numbers. 1 leaps to mind. They don't have to be universally unique: just unique inside that type.

这篇关于套接字上的Protobuf-net序列化.找不到无参数的构造函数ProtoException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆