使用UdpClient C#发送对象

时间:2011-06-12 10:17:29

标签: c# udpclient

我目前正在使用Visual Studio 2010进行测试。我创建了一个客户端和服务器,它们都将通过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);
        }
    }

我该如何解决这个问题? 提前致谢

3 个答案:

答案 0 :(得分:3)

BinaryFormatter与类型元数据密切相关。这里不是一个好选择,因为你有不同的类型。实际上IMO它不是一个好的选择:)它不是版本宽容,并且不便携。

我会在这里公开推荐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(stream,object)来写入数据。

如果需要,您也可以在没有属性的情况下工作,它需要一点更多设置,但不多。

答案 1 :(得分:3)

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

另请注意,UDP不可靠。无法保证您的邮件完全到达。

答案 2 :(得分:2)

您可能遇到了不满意的依赖问题。这可能是由不同的命名空间或尝试序列化未安装在服务器上的外部组件引起的。

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

您应该使用相同的命名空间。这就是他们的目的。此外,它们使处理依赖性更容易。 MyApp.ServerMyApp.Client交谈看起来不错;)。

我希望你明白这一点。