0

私は現在、C#XNAで作成されたゲームに取り組んでいます。ネット経由で大量のデータ(約96kb)を送信する必要があるため、インターネットで見つけた文字列コンプレッサー/デコンプレッサーコードを使用しています。コードは次のようになります。

        public static string Compress(string text)
    {
        byte[] buffer = Encoding.UTF8.GetBytes(text);
        MemoryStream ms = new MemoryStream();
        using (GZipStream zip = new GZipStream(ms, CompressionMode.Compress, true))
        {
            zip.Write(buffer, 0, buffer.Length);
        }

        ms.Position = 0;
        MemoryStream outStream = new MemoryStream();

        byte[] compressed = new byte[ms.Length];
        ms.Read(compressed, 0, compressed.Length);

        byte[] gzBuffer = new byte[compressed.Length + 4];
        System.Buffer.BlockCopy(compressed, 0, gzBuffer, 4, compressed.Length);
        System.Buffer.BlockCopy(BitConverter.GetBytes(buffer.Length), 0, gzBuffer, 0, 4);

        return Convert.ToBase64String(gzBuffer);
    }

    public static string Decompress(string compressedText)
    {
        byte[] gzBuffer = Convert.FromBase64String(compressedText);
        using (MemoryStream ms = new MemoryStream())
        {
            int msgLength = BitConverter.ToInt32(gzBuffer, 0);
            ms.Write(gzBuffer, 4, gzBuffer.Length - 4);

            byte[] buffer = new byte[msgLength];

            ms.Position = 0;
            using (GZipStream zip = new GZipStream(ms, CompressionMode.Decompress))
            {
                zip.Read(buffer, 0, buffer.Length);
            }

            return Encoding.UTF8.GetString(buffer);
        }
    }

これは次のように機能します。-サーバーは文字列コンプレッサーを使用して文字列を圧縮し、クライアントに送信した後。-クライアントは圧縮された文字列を受け取り、使用できるように解凍します。

ここで奇妙なのは、ゲームを単独でテストしているときにコードが機能することです。つまり、サーバーとクライアントを同じマシンで実行します。また、友人がサーバーをホストしている友人とテストしているときにも機能し、接続します。しかし、私がサーバーをホストしていて、彼が接続しているとき、それは私の友人のために機能していません。彼が私のサーバーに接続すると、「int msgLength = BitConverter.ToInt32(gzBuffer、0);」で「Indexoutofrange」を受け取ります。 幸運なことに彼が入ることもありますが、ほとんどの場合失敗してそのエラーを返します。サーバーが文字列全体を送信していない可能性がありますか?ネットワーク送信にLidgrengen3を使用しており、圧縮された文字列はnetMsg.Write(compressedstring);として送信されます。

何か案は :) ?ありがとう!

4

1 に答える 1

2

複数の場所で同じ誤った仮定を行っていStream.Readます。これにより、要求したすべてのデータが一度に返されます。戻り値を無視しています。そうしないでください...MemoryStream確かに、十分なデータがあると仮定すると、sは問題ないはずです。さらに、このMemoryStream.ToArrayメソッドを使用してバイト配列に変換することもできます。

ここでは、クライアントが文字列をどのように受信しているかを示していません。どこから文字列を取得していますか?

サーバーが送信する文字列と、クライアントが受信する文字列をログに記録する必要があります。これは絶対的な最初のステップなので、データが実際に保存されているかどうかを確認できます。

クライアントが空の文字列を解凍しようとしているのではないかと思います。つまりConvert.FromBase64、空のバイト配列を返していますが、受信している文字列がわかるまで、進行するのは困難です。

于 2010-06-15T19:22:29.760 に答える