1

サーバー アプリケーションとクライアント アプリケーションがあり、それらは NetworkStream 経由で通信しています。サーバーでは、オブジェクトをバイナリシリアル化し、NetworkStream 経由で送信します。クライアントで読み取られ、逆シリアル化されます。しかし、エラーがスローされます: バイナリ ストリーム '0' に有効な BinaryHeader が含まれていません。考えられる原因は、無効なストリームまたはシリアル化と逆シリアル化の間のオブジェクト バージョンの変更です。最初に NetworkStream の長さを確認しましたが、シリアル化されたオブジェクトを送信した後、サーバーとクライアントで同じです。次に、クライアントへのサーバー参照を追加し、Server.SaveData を使用して、デシリアライズ時にまったく同じクラスになるようにします。

次に、サーバー上の同じオブジェクトをシリアル化および逆シリアル化してみました。以下のコードは完全に機能します。

stream.Read(buffer, 0, total);
network_stream.Write(buffer, 0, total);

network_stream.Read(buffer, 0, total);
stream.Position = 0;
stream.Write(buffer, 0, total);

SaveData savedata = (SaveData)formatter.Deserialize(stream);

サーバーからの完全なコードは次のとおりです。

Stream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();

current_state.saveData(map, red, blu);
formatter.Serialize(stream, current_state);

int total = (int)stream.Length;
byte[] buffer = new byte[total];

writer.WriteLine(total.ToString());
writer.Flush();

stream.Read(buffer, 0, total);
network_stream.Write(buffer, 0, total);

stream.Close();

そしてクライアント側:

Stream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();

while (reader.Peek() == '\0') { reader.Read(); } //solved the problem, idkw
int total = Convert.ToInt32(reader.ReadLine().ToString());
byte[] buffer = new byte[total];

network_stream.Read(buffer, 0, total);
stream.Position = 0;
stream.Write(buffer, 0, total);
stream.Position = 0;

Console.Write(stream.Length.ToString());

Server.SaveData current_state = (Server.SaveData)formatter.Deserialize(stream); //here is the problem

stream.Close();
4

1 に答える 1

0

データを直接シリアライズ/デシリアライズしないのはなぜNetworkStreamですかMemoryStream?

ちょっとした例。

サーバーとクライアントが交換するために使用するデータ構造があると仮定します(あなたの場合、データ構造はですcurrent_state)。

[Serializable]
public class UserData : ISerializable
{
    public string Text { get; private set; }
    public int Number { get; private set; }

    public UserData(string text, int number)
    {
        Text = text;
        Number = number;
    }

    protected UserData(SerializationInfo info, StreamingContext context)
    {
        Text = info.GetString("Text");
        Number = info.GetInt32("Number");
    }

    void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Text", Text);
        info.AddValue("Number", Number);
    }
}

データ構造を送信するには (クライアント側などから):

using (var networkStream = tcpClient.GetStream())
{
    var userData = new UserData("Hello.", 9);

    var binaryFormatter = new BinaryFormatter();
    binaryFormatter.Serialize(networkStream, userData);
}

データ構造を受け取るには (サーバー側など):

var binaryFormatter = new BinaryFormatter();
using (var networkStream = tcpClient.GetStream())
{
    while (networkStream.DataAvailable)
    {
        var receivedData = (UserData)binaryFormatter.Deserialize(networkStream);
    }
}
于 2013-02-28T14:10:09.923 に答える