我想要GZipStream不发送

时间:2014-08-20 11:30:10

标签: c# .net sockets stream

我正在尝试在套接字上使用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需要时发送消息。

有什么想法吗?

谢谢。

更新:

我已经创建了一个完整的snipet。

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();
}

2 个答案:

答案 0 :(得分:0)

使用接受bool参数的overload of the GZipStream constructor来说明之后是否打开基础流:

using (var zip = new GZipStream(networkStream, CompressionMode.Compress, true))
{
    zip.Write (....);
}

您可能想要考虑另一端对压缩数据结束的了解程度,但是我不知道这是否隐含在gzip流中。

另一种方法是首先写入MemoryStream,然后发送(压缩)长度,然后发送压缩数据......然后另一端可以读取长度,读取那么多数据,解压缩,然后准备好阅读下一条消息。

答案 1 :(得分:0)

使用带有布尔值的GZipStream constructor来确定是否打开基础流:

  

GZipStream构造函数(Stream,CompressionLevel,Boolean)

     

使用指定的流和压缩级别初始化GZipStream类的新实例,并可选择使流保持打开状态。

using (GZipStream zip = new GZipStream(networkStream, CompressionMode.Compress, true))
{
    zip.Write (....);
}