我试图在套接字上使用GzipStream。为了达到这个目的,我使用如下命令:
using System.IO.Compression;
TcpClient _client = null;
// ...
// ... Connection
NetworkStream networkStream = _client.GetStream();
GZipStream zip = new GZipStream(networkStream, CompressionMode.Compress);
当我发送消息时,我使用GZipStream方法,Write和Flush:
zip.Write (....);
zip.Flush();
问题是,当我运行Flush方法时,消息没有发送。消息只有在我关闭GZipStream(运行GZipStream类的close方法)时才会发送。
我正在尝试这种方法:
using (GZipStream zip = new GZipStream(networkStream, CompressionMode.Compress))
{
zip.Write (....);
}
但是,当zip类超出使用范围并被处置(关闭)时,networkStream实例也被关闭并处置。
如何避免这种行为?我在一个实时应用程序中运行这个,我需要在我想要的时候发送消息,而不是当GZipStream想要的时候。
任何想法?
谢谢。更新:
我已经创建了一个完整的代码片段。
using (var client = new TcpClient("127.0.0.1", 1514))
{
var networkStream = client.GetStream();
client.SendBufferSize = 1;
client.NoDelay = true;
using (Stream zip = new GZipStream(networkStream, CompressionMode.Compress, true))
{
byte[] dgram = CreateMessage("Testing line 1");
zip.Write(dgram, 0, dgram.Length);
}
networkStream.Flush();
// Next using block don't send anything. The server side does't receive anything.
// No exception is raised. It seems ok, but anything is sent
using (Stream zip = new GZipStream(networkStream, CompressionMode.Compress, true))
{
byte[] dgram = CreateMessage("Testing line 2");
{
zip.Write(dgram, 0, dgram.Length);
}
}
networkStream.Flush();
}
使用GZipStream
构造函数的重载,该构造函数接受一个bool
参数来决定是否在之后保持底层流打开:
using (var zip = new GZipStream(networkStream, CompressionMode.Compress, true))
{
zip.Write (....);
}
您可能想要考虑另一端如何轻松地了解压缩数据的结束,然而-我不知道这是否隐含在gzip流中。
另一种方法是先写入MemoryStream
,然后发送(压缩)长度,然后发送压缩数据…然后另一端可以读取长度,读取那么多数据,解压缩,然后准备读取下一条消息。
使用接受布尔值的GZipStream
构造函数来确定是否保持底层流打开:
GZipStream构造函数(Stream, CompressionLevel, Boolean)
使用指定的流和压缩级别初始化GZipStream类的新实例,并可选择保持流打开。
using (GZipStream zip = new GZipStream(networkStream, CompressionMode.Compress, true))
{
zip.Write (....);
}