ネットワーク ストリームを使用して通信する 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 を作成します。
どうしたの ?すべての圧縮ストリームの実装が「データストリームにエラーがあります」というエラーで失敗しているため、私と私のコードに違いないという予感があります。一方、圧縮を削除してネットワークストリームのみを使用しても問題はありません。これにより、問題は圧縮コードにあるに違いないと思います。
これは誰にとってもおなじみの音ですか?そして、私たちがそれに取り組んでいる間、ネットワークストリームをラップするのに適した(他の)圧縮ストリームの実装を知っている人はいますか?