У меня есть пара клиент-серверных программ на C #, которые общаются с помощью сетевого потока.Все работает нормально, как и без сжатия.Теперь я хотел бы уменьшить использование полосы пропускания, поэтому я хочу использовать сжатую обертку вокруг моего сетевого потока.
Я пробовал SharpZipLib, DotNetZip, собственный CZ GZipStream - но я не могу заставить ни одного из нихwork.
SharpZipLib имеет проблемы с сбросом, и применение указанного здесь исправления: http://community.sharpdevelop.net/forums/p/7855/22139.aspx приводит к исключению "Контрольная сумма заголовка недопустима".
Использование DlateNetZip DeflateStream приводит к исключению ZLibException («Плохое состояние (недопустимая длина хранимых блоков)»);
GZipStream дает мне исключение System.IO.InvalidDataException, в котором говорится «Магическое число в заголовке GZip неверно. Убедитесь, что вы передаете поток GZip»..
Способ, который я реализовал, заключается в том, что каждый раз, когда моя инфраструктура должна отправлять массив байтов, я создаю новую оболочку потока сжатия вокруг существующего сетевого потока, записываю байты в поток сжатия изатем промойте, закройте и утилизируйте его.Это сделано для того, чтобы каждый 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();
и немедленно создает новый inputStream, снова вызывая CreateInputStreamWrapper.
Так что же происходит?Так как все реализации потока сжатия терпят неудачу с ошибками, которые сводятся к «есть ошибка в потоке данных», у меня есть догадка, это должны быть я и мой код.С другой стороны, если я снимаю сжатие и просто использую сетевой поток, проблем нет, что заставляет меня думать, что проблема должна заключаться в коде сжатия.
Звучит ли это кому-нибудь знакомо?И в то время как мы находимся в этом, кто-нибудь знает о любых (других) реализациях потока сжатия, которые подходят для обтекания сетевого потока?