C# 使用UdpClient C发送对象#

C# 使用UdpClient C发送对象#,c#,udpclient,C#,Udpclient,我目前正在VisualStudio2010中进行测试。我制作了一个客户端和服务器,两者都将通过UdpClient连接 我想从客户端向服务器发送一个对象。我有两种方法将对象转换为字节,并将其转换为对象。现在,当我测试我的应用程序时,一旦在服务器上收到它,我就不能将它转换回对象 我的服务器看到接收到该对象,并尝试将其从字节转换为该对象,但这会导致错误 System.Runtime.Serialization.SerializationException was unhandled Message

我目前正在VisualStudio2010中进行测试。我制作了一个客户端和服务器,两者都将通过UdpClient连接

我想从客户端向服务器发送一个对象。我有两种方法将对象转换为字节,并将其转换为对象。现在,当我测试我的应用程序时,一旦在服务器上收到它,我就不能将它转换回对象

我的服务器看到接收到该对象,并尝试将其从字节转换为该对象,但这会导致错误

System.Runtime.Serialization.SerializationException was unhandled   Message=Unable to find assembly
这似乎没问题,因为两个应用程序都位于不同的命名空间中

这些是我转换的方法;在客户端和服务器上都是相同的

public byte[] ToBytes() {
        using (MemoryStream stream = new MemoryStream()) {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, this);

            stream.Position = 0;

            byte[] byteRij = new byte[1024];

            stream.Read(byteRij, 0, (int)stream.Length);

            return byteRij;
        }
    }

    public static Datagram ToDatagram(byte[] rij) {
        using (MemoryStream stream = new MemoryStream()) {
            stream.Write(rij, 0, rij.Length);

            stream.Position = 0;

            BinaryFormatter formatter = new BinaryFormatter();
            return (Datagram)formatter.Deserialize(stream);
        }
    }
我如何解决这个问题?
提前感谢

您可能遇到依赖关系不满意的问题。这可能是由于不同的名称空间或试图序列化服务器上未安装的外部组件造成的

假设:您发送类型为
MyApp1.MyFoo
的对象
MyFoo
也在您的服务器中定义,但定义为
MyApp2.MyFoo
(这非常愚蠢,意味着您必须修复您的设计)。服务器不知道如何创建
MyApp1.MyFoo
的对象,因为它不够聪明,无法发现它也定义了这个类,但名为
MyApp2.MyFoo

您应该使用相同的名称空间。这就是他们的目的。此外,它们使处理依赖关系变得更容易。而且
MyApp.Server
MyApp.Client
交谈看起来不错;)


我希望您能理解这一点。

BinaryFormatter与类型元数据紧密相连。这不是一个好的选择,因为你有不同的类型。事实上,在我看来,这并不是一个好的选择:)它的版本容忍度不高,而且不可移植

我将在这里公开推荐protobuf net(披露:我写的)。它是免费的OSS,但使用谷歌的protobuf格式来解决所有BF问题。与BinaryFormatter相比,它的设置和使用非常简单,速度更快,输出更小。由于它是基于合同的,您可以在每一端有不同的类型,因为他们同意合同(匹配字段号等)

例如:

[ProtoContract]
public class Foo {
    [ProtoMember(1)]
    public string X {get;set;}
    [ProtoMember(2)]
    public int Y {get;set;}
}
然后只需使用ProtoBuf.Serializer.Serialize(流、对象)来写入数据


如果需要,您也可以不使用attribute,这需要更多的设置,但不需要太多。

您需要将所有序列化的类放在类库项目中。在服务器和客户端中都使用该库


还要注意,UDP是不可靠的。无法保证消息到达。

如果序列化表单大于1024字节,则
ToBytes()
方法将无法正常工作。为什么不使用?请注意,这只是二进制格式化程序的要求。大多数其他序列化程序都不需要这个。是的,我想我必须创建一个类库。这是有道理的。另外,我使用UDP只是为了了解我有什么选择。谢谢