5

我目前正在 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);
        }
    }

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

4

3 回答 3

3

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

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

于 2011-06-12T11:12:48.817 回答
3

BinaryFormatter 与类型元数据密切相关。这不是一个好的选择,因为你有不同的类型。实际上,IMO 无论如何都不是一个好的选择 :) 它对版本的容忍度不是很高,也不是可移植的。

我会在这里公开推荐 protobuf-net(披露:我写的)。它是免费的 OSS,但使用 google 的 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) 来写入数据。

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

于 2011-06-12T11:07:57.793 回答
2

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

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

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

我希望你明白这一点。

于 2011-06-12T10:45:21.197 回答