2

C# のソケットについて学習しようとしており、練習用にマルチプレイヤー ゲームを作成することにしました。私はソケットの送信にかなりの距離を置いていますが、他のクライアントからクラスを受信して​​逆シリアル化した後、ブール値が常に true になるという奇妙な問題があります。

ここで問題が発生します。

void OnDataReceived(object sender, ConnectionEventArgs e)
{
    Connection con = (Connection)e.SyncResult.AsyncState;
    Game.ScoreBoard[currentPlayer] = Serializer.ToScoreCard(con.buffer); //Here
    ...
}

Game.ScoreBoard[currentPlayer].Localが常に true になってしまい、何が問題なのかさっぱりわかりません。他の値は正常に機能しているようです。Connection は、IP、ソケットを含むクラスであり、接続などを管理します。バッファ サイズは現在 30 000 です。問題がないことを確認するために拡大してみました。

クラスからの関連情報は次のとおりです。

public ScoreCard(SerializationInfo info, StreamingContext context)
{
    name = (string)info.GetValue("Name", typeof(string));
    played = (bool[])info.GetValue("Played", typeof(bool[]));
    scores = (int[])info.GetValue("Scores", typeof(int[]));
    bonusScore = (int)info.GetValue("bonusScore", typeof(int));
    local = (bool)info.GetValue("Local", typeof(bool));
}

public void GetObjectData(SerializationInfo info, StreamingContext context)
{
    info.AddValue("Scores", scores, typeof(int[]));
    info.AddValue("Played", played, typeof(bool[]));
    info.AddValue("Name", name, typeof(string));
    info.AddValue("bonusScore", bonusScore, typeof(int));
    info.AddValue("Local", local, typeof(bool));
}

そして、シリアライザークラスは次のとおりです。

static class Serializer
{
    public static byte[] ToArray(object data)
    {
        MemoryStream stream = new MemoryStream();
        BinaryFormatter b = new BinaryFormatter();
        b.Serialize(stream, data);
        return stream.ToArray();
    }

    public static ScoreCard ToScoreCard(byte[] data)
    {
        ScoreCard sc;
        MemoryStream stream = new MemoryStream(data);
        BinaryFormatter b = new BinaryFormatter();
        sc = (ScoreCard)b.Deserialize(stream);
        return sc;
    }
}

どうすればいいのか、あるいは提供された情報があなたが私の問題を解決するのに十分であるかどうかさえわかりません. 必要に応じて、より多くの情報を提供できます。そのブール値だけが正しく機能しないように見えるのは奇妙だと思います。

編集:私は問題を見つけました、そして、いつものように、それは単純な愚かな間違いでした. まあ、少なくとも自分のバイナリフォーマッタを作ることを学びました。みんなありがとう :)

4

1 に答える 1

1

BinaryFormatterのパフォーマンスはひどいです。シリアル化するすべてのオブジェクトには大量のオーバーヘッドがあり、私の経験では、オブジェクトをバイナリでシリアル化するのに40秒以上かかるフォーマッターは、カスタムバイナリライターによって1秒未満で実行できます。

あなたはこれを考慮したいかもしれません:

static class Serializer
{
    public static byte[] MakePacket(ScoreCard data)
    {
        MemoryStream stream = new MemoryStream();
        using (StreamWriter sw = new StreamWriter(stream)) {
            sw.Write(1); // This indicates "version one" of your data format - you can modify the code to support multiple versions by using this
            sw.Write(data.Name);
            sw.Write(data.scores.Length);
            foreach (int score in data.scores) {
                sw.Write(score);
            }
            sw.Write(data.played.Length);
            foreach (bool played in data.played) {
                sw.Write(played );
            }
            sw.Write(data.bonusScore);
            sw.Write(data.local);
        }
        return stream.ToArray();
    }

    public static ScoreCard ReadPacket(byte[] data)
    {
        ScoreCard sc = new ScoreCard();
        MemoryStream stream = new MemoryStream(data);
        using (StreamReader sr = new StreamReader(stream)) {
            int ver = sr.ReadInt32();
            switch (ver) {
                case 1:
                    sc.name = sr.ReadString();
                    sc.scores = new int[sr.ReadInt32()];
                    for (int i = 0; i < sc.scores.Length; i++) {
                        sc.scores[i] = sr.ReadInt32();
                    }
                    sc.played = new bool[sr.ReadInt32()];
                    for (int i = 0; i < sc.scores.Length; i++) {
                        sc.played [i] = sr.ReadBool();
                    }
                    sc.BonusScore = sr.ReadInt32();
                    sc.Local = sr.ReadBool();
                    break;
                default: 
                    throw new Exception("Unrecognized network protocol");
            }
        }
        return sc;
    }
}
于 2012-07-23T22:37:31.147 に答える