5

現在、VisualStudio2010でテストしています。UdpClientを介して接続するクライアントとサーバーを作成しました。

クライアントからサーバーにオブジェクトを送信したい。オブジェクトをバイトに変換する方法と、オブジェクトに変換する方法が2つあります。これで、アプリケーションをテストするときに、サーバーで受信したアプリケーションをオブジェクトに戻すことができなくなりました。

サーバーはオブジェクトが受信されたことを確認し、それをバイトからオブジェクトに変換しようとしますが、これによりエラーが発生します。

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

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 に答える
3

シリアル化されたすべてのクラスをクラスライブラリプロジェクトに配置する必要があります。サーバーとクライアントの両方でそのライブラリを使用します。

また、UDPは信頼できないことに注意してください。あなたのメッセージがまったく届くという保証はありません。

于 2011-06-12T11:12:48.817 に答える
2

依存関係が満たされないという問題が発生している可能性があります。これは、名前空間が異なるか、サーバーにインストールされていない外部コンポーネントをシリアル化しようとしたことが原因である可能性があります。

説明:タイプのオブジェクトを送信しますMyApp1.MyFoo
クラスMyFooもサーバーで定義されていますが、として定義されていますMyApp2.MyFoo(これは非常にばかげており、設計を修正する必要があることを意味します)。サーバーは、オブジェクトを作成する方法を知りません。これは、サーバーMyApp1.MyFooにもこのクラスが定義されているが、名前が付けられていることを確認するのに十分なほど賢くないためMyApp2.MyFooです。

同じ名前空間を使用する必要があります。これが彼らの目的です。また、依存関係の処理が容易になります。そして、MyApp.Server話をするのはよさMyApp.Clientそうだ;)。

私はあなたがポイントを得ることを望みます。

于 2011-06-12T10:45:21.197 に答える