9

I'm building an network application that needs to be able to switch from normal network traffic to a zlib compressed stream, mid stream. My thoughts on the matter involve boolean switch that when on will cause the network code to pass all the data through a class that I can feed IEnumerable<byte> into, and then pull out the decompressed stream, passing that on to the already existing protocol parsing code.

Things I've looked at:

  • ZLib.NET - It seems a little... Ecclectic, and not quite what I want. Would still make a decent start to build off though. (Jon Skeet's comments here hardly inspire me either.)
  • SharpZipLib - This doesn't seem to support zlib at all? Can anyone confirm or deny this?

I would very much prefer and all managed solution, but let's have at it... are there any other implementations of this library out there in .NET, that might be better suited to what I want to do, or should I take ZLib.NET and build off that as a start?

PS:

Jon's asked for more detail, so here it is.

I'm trying to implement MCCP 2. This involves a signal being sent in the network stream, and everything after this signal is a zlib compressed data stream. There's links to exactly what they mean by that in the above link. Anyway, to be clear, I'm on the recieving end of this (client, not server), and I have a bunch of data read out of the network stream already, and the toggle will be in the middle of this (in all likelyhood atleast), so any solution needs to be able to have some extra data fed into it, before it takes over the NetworkStream (or I manually feed in the rest of the data).

Community
  • 1
  • 1
Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222
  • Would the header for the zip start when you were given a specific packet? – Chris S Feb 04 '09 at 21:35
  • I have no idea about this. Personally I don't pay too much attention to that level of detail. I'd suspect that'd be server implementation specific, there's no mention of it in any of the description documentation. – Matthew Scharley Feb 04 '09 at 21:53
  • Did you ever get a good library for MCCP 2? – m4tt1mus Jul 28 '11 at 22:00
  • @m4tt1mus: I don't believe I ever got this working. I could try to see if I can dig up my code though, if you're interested. I think I still have it around somewhere. – Matthew Scharley Jul 29 '11 at 00:17
  • i might just see if i can use the c libraries in my .NET project somehow. I'm definitely no that great at C though. – m4tt1mus Jul 29 '11 at 03:08
  • @m4tt1mus: That's always possible. Look into interop or p/invoke, both ways work. – Matthew Scharley Jul 29 '11 at 03:42
  • @MatthewScharley Hello from 13 years after you posted, but I'm here to just say that I was able to implement MCCP2 decompression with SharpZipLib. .NET 6 has ZLibStream, but the need to switch between decompressed to compressed in the middle of a message/packet (after the data has been read from the stream) made it infeasible to use. /wave – Dan Rigby Apr 16 '22 at 21:22

5 Answers5

6

SharpZipLib does support ZLib. Look in the FAQ.

Additionally, have you checked whether the System.IO.Compression namespace supports what you need?

I wouldn't use an IEnumerable<byte> though - streams are designed to be chained together.

EDIT: Okay... it sounds like you need a stream which supports buffering, but with more control than BufferedStream provides. You'd need to "rewind" the stream if you saw the decompression toggle, and then create a GZipStream on top of it. Your buffer would need to be at least as big as your biggest call to Read() so that you could always have enough buffer to rewind.

Community
  • 1
  • 1
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I agree on your point about the IEnumerable thing... but the fact of the matter is, I can't find a way to push data that I've already read into the zlib stream (since this transition happens midstream) before connecting the network stream to it. Any suggestions there? – Matthew Scharley Feb 04 '09 at 21:01
  • It's not entirely clear to me what you're doing. Do you have two different output streams, and you want to switch between them? In fact, I don't really "get" whether you're reading or writing. More explanation in the question might yield better ideas :) – Jon Skeet Feb 04 '09 at 21:02
  • Ok, I wrapped my NetworkStream with a BufferedStream and... Nothing. BeginRead just hangs there doing nothing. Presumably it's waiting for a full buffers worth first, but I as using a 4k read buffer before, and obviously a login screen isn't going to take up that much space. – Matthew Scharley Feb 05 '09 at 00:38
  • I did away with the BufferedStream in favour of just reading byte by byte anyway, since my processing function is a byte by byte state machine anyway. – Matthew Scharley Feb 05 '09 at 02:10
  • Cool - that makes life a lot simpler :) – Jon Skeet Feb 05 '09 at 06:06
3

Included in DotNetZip there is a ZlibStream, for compressing or decompressing zlib streams of data. You didn't ask, but there is also a GZipStream and a DeflateStream. As well as a ZlibCodec class, if that is your thing. (just inflates or deflates buffers, as opposed to streams).

DotNetZip is a fully-managed library with a liberal license. You don't need to use any of the .zip capability to get at the Zlib stuff. And the zlib stuff is packaged as a separate (smaller) DLL just for this purpose.

Cheeso
  • 189,189
  • 101
  • 473
  • 713
0

I can recommend you Gerry Shaw's zlib wrapper for .NET:

http://www.organicbit.com/zip/

Dirk Vollmar
  • 172,527
  • 53
  • 255
  • 316
  • This is prerelease, and I'm building against mono, so I'm tempted to just save the headache and steer clear, but I'll still check it out. – Matthew Scharley Feb 04 '09 at 21:13
  • We have been using this in production for more than 2 years now, both with .NET and with Mono. No pain so far. – Dirk Vollmar Feb 05 '09 at 15:35
0

As far as I know the ZLib (gzip) library doesn't support listing the files in the header. Assuming that matters to you, but it seems a big shortcoming. This was when I used the sharp zip library a while ago, so I'm willing to delete this :)

Chris S
  • 64,770
  • 52
  • 221
  • 239
  • This is compression over a network for a remote console. There is no filename. So it doesn't quite matter. But as a response to your answer, there's quite a few compressions that don't (gzip and bzip2 come to mind) which is why they are generally used in tandem with tar. – Matthew Scharley Feb 04 '09 at 21:17
  • This was actually the .NET library for compression (gzip off the top of my head) that didn't display the filenames – Chris S Feb 04 '09 at 21:31
  • Sorry monoxide I should've read the question more clearly...bye bye post in 10 minutes – Chris S Feb 04 '09 at 21:32
-1

Old question, but System.IO.Compression.DeflateStream is actually the right answer if you need proper zlib support:

Starting with the .NET Framework 4.5, the DeflateStream class uses the zlib library. As a result, it provides a better compression algorithm and, in most cases, a smaller compressed file than it provides in earlier versions of the .NET Framework.

Doesn't get better than that.

atlaste
  • 30,418
  • 3
  • 57
  • 87
  • The zlib compression format != the zlib library. The zlib library contains implementations of both deflate (RFC 1951) and zlib (RFC 1950) compression formats. – Nick Whaley Jun 30 '21 at 02:41