GZipStream not send when I want

I'm trying to use GzipStream over a socket. For this purpose I use something like this.

using System.IO.Compression;    
TcpClient _client = null;

// ...
// ... Connection 

NetworkStream networkStream = _client.GetStream();
GZipStream zip = new GZipStream(networkStream, CompressionMode.Compress);

when I send a message I use GZipStream methods, Write and Flush:

zip.Write (....);
zip.Flush();

The problem is that when I run Flush method the message isn't sent. The messages are only sent when I close GZipStream (running Close method of GZipStream class).

I'm trying with this approach:

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

but, when zip class is out of using scope and is disposed (closed), networkStream instance is closed and disposed too.

How can avoid this behaviour? I'm running this in a realtime application and I need to send messages when I want not when GZipStream wants.

Any ideas?

Thank you.

UPDATE:

I have create a complete 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();
}
Jon Skeet
people
quotationmark

Use the overload of the GZipStream constructor which accepts a bool parameter to say whether to leave the underlying stream open afterwards:

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

You might want to consider how easily the other end is going to know about the end of the compressed data, however - I don't know whether that's implicit within a gzip stream.

An alternative would be to write to a MemoryStream first, and send the (compressed) length and then the compressed data... then the other end could read the length, read that much data, decompress it, and be ready to read the next message afterwards.

people

See more on this question at Stackoverflow