2

ネットワーク ストリームを使用して通信する C# クライアント サーバー プログラムのペアがあります。圧縮なしですべて正常に動作します。ここで、帯域幅の使用量を減らしたいので、ネットワーク ストリームの周りに圧縮ラッパー ストリームを使用したいと考えています。

SharpZipLib、DotNetZip、C# 独自の GZipStream を試しましたが、どれも機能しません。

SharpZipLib には、フラッシュに問題があり、ここで指定された修正プログラムを適用すると、http://community.sharpdevelop.net/forums/p/7855/22139.aspx例外「ヘッダー チェックサムが不正です」が発生します。

DotNetZip の DeflateStream を使用すると、ZLibException("Bad state (invalid stored block lengths)"); が発生します。

GZipStream は、「GZip ヘッダーのマジック ナンバーが正しくありません。GZip ストリームを渡していることを確認してください。」という System.IO.InvalidDataException を返します。

私が実装した方法は、バイトの配列がフレームワークによって送信される必要があるたびに、既存のネットワークストリームの周りに新しい圧縮ストリームラッパーを作成し、バイトを圧縮ストリームに書き込み、フラッシュ、クローズ、および破棄することです. これにより、各 WriteMessage(byte[] blah) が、すぐにフラッシュされる独自の状態に依存しない圧縮ストリームを使用するようになります。どのストリームも元のネットワーク ストリームを閉じないように注意しました。

                using (System.IO.Stream outputStream = CreateOutputStreamWrapper(_networkStream))
                {
                    outputStream.Write(messageBytes, 0, messageBytes.Length);
                    outputStream.Flush();
                    outputStream.Close();
                    outputStream.Dispose();
                }

基本的に、私の DecompressionStream は次のように作成されます(オプションはコメントアウトされています)

protected System.IO.Stream CreateInputStreamWrapper(System.IO.Stream inInputStream)
{
        //return new DeflateStream(inInputStream, CompressionMode.Decompress, true);
        //return new BZip2InputStream(inInputStream, true);
        return new GZipStream(inInputStream, System.IO.Compression.CompressionMode.Decompress, true);
}

として始まりました

_inputStream.BeginRead(_buffer, 0, _buffer.Length, new AsyncCallback(ReceiveCallback), null);

次に、ReceiveCallback でデータが読み取られ、ストリームがフラッシュされ、閉じられ、破棄されます。

            //Get received bytes count
            var bytesRead = _inputStream.EndRead(ar);
            _inputStream.Flush();
            _inputStream.Close();
            _inputStream.Dispose();

CreateInputStreamWrapper を再度呼び出して、すぐに新しい inputStream を作成します。

どうしたの ?すべての圧縮ストリームの実装が「データストリームにエラーがあります」というエラーで失敗しているため、私と私のコードに違いないという予感があります。一方、圧縮を削除してネットワークストリームのみを使用しても問題はありません。これにより、問題は圧縮コードにあるに違いないと思います。

これは誰にとってもおなじみの音ですか?そして、私たちがそれに取り組んでいる間、ネットワークストリームをラップするのに適した(他の)圧縮ストリームの実装を知っている人はいますか?

4

1 に答える 1

4

他の誰かがこれを読んだ場合に備えて、DotNetZip の ZLib ストリームには FlushMode フラグがあり、ネットワーク関連 (「同期」および「フル」モード) と互換性のあるフラッシュを設定できます。

于 2012-03-13T08:26:48.297 に答える