C.循环压缩+发送(gzip)ZLIB [英] C. Loop compression + send (gzip) ZLIB

查看:102
本文介绍了C.循环压缩+发送(gzip)ZLIB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在用C语言构建HTTP服务器。

I'm currently building an HTTP server in C.

请注意这段代码:

  #define CHUNK 0x4000
  z_stream strm;
  unsigned char out[CHUNK];
  int ret;
  char buff[200];

  strm.zalloc = Z_NULL;
  strm.zfree = Z_NULL;
  strm.opaque = Z_NULL;

  int windowsBits = 15;
  int GZIP_ENCODING = 16;

  ret = deflateInit2(&strm, Z_BEST_SPEED, Z_DEFLATED, windowsBits | GZIP_ENCODING, 1, 
                     Z_DEFAULT_STRATEGY);
  fill(buff); //fill buff with infos

  do {
  strm.next_in = (z_const unsigned char *)buff;
  strm.avail_in = strlen(buff);
      do {
        strm.avail_out = CHUNK;
        strm.next_out = out;
        ret = deflate(&strm, Z_FINISH);
       } while (strm.avail_out == 0);

  send_to_client(out); //sending a part of the gzip encoded string
  fill(buff);
  }while(strlen(buff)!=0);

这个想法是:我正在尝试一个接一个地发送gzip缓冲,

The idea is : I'm trying to send gzip'ed buffers, one by one, that (when they're concatened) is a whole body request.

BUT:目前,我的客户端(浏览器)仅获得第一个缓冲区的信息。

BUT : for now, my client (a browser) only get the infos of the first buffer. No errors at all though.

我如何完成这项工作,如何在循环中gzip一些缓冲区,以便每次(在循环中)发送? p>

How do I achieve this job, how to gzip some buffers inside a loop so I can send them everytime (in the loop) ?

推荐答案

首先,在每个 deflate()调用。您的代码将丢弃内部循环中生成的压缩数据。在此示例中,在 deflate()之后您将需要以下内容:

First off, you need to do something with the generated deflate data after each deflate() call. Your code discards the compressed data generated in the inner loop. From this example, after the deflate() you would need something like:

        have = CHUNK - strm.avail_out;
        if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
            (void)deflateEnd(&strm);
            return Z_ERRNO;
        }

这就是您的 send_to_client 需要,发送个字节。

That's where your send_to_client needs to be, sending have bytes.

在您的情况下,您的 CHUNK buff 大得多,该循环始终仅执行一次,因此您不会丢弃任何数据。但是,这只是由于 Z_FINISH 而发生的,因此,在进行下一个修复时,将使用当前代码丢弃数据。

In your case, your CHUNK is so much larger than your buff, that loop is always executing only once, so you are not discarding any data. However that is only happening because of the Z_FINISH, so when you make the next fix, you will be discarding data with your current code.

第二,每次输入不超过199个字节后,您将完成 deflate()流。这将大大限制您可以获得的压缩量。此外,您将发送单独的gzip流,大多数浏览器仅会解释第一个gzip流。 (这实际上是这些浏览器中的错误,但我不认为它们会得到解决。)

Second, you are finishing the deflate() stream each time after no more than 199 bytes of input. This will greatly limit how much compression you can get. Furthermore, you are sending individual gzip streams, for which most browsers will only interpret the first one. (This is actually a bug in those browsers, but I don't imagine they will be fixed.)

您需要给压缩器至少10到100千字节为了得到体面的压缩而工作。您需要使用 Z_NO_FLUSH 而不是 Z_FINISH ,直到获得最后一个 buff 您要发送。然后,您使用 Z_FINISH 。同样,请看一下示例并阅读注释。

You need to give the compressor at least 10's to 100's of Kbytes to work with in order get decent compression. You need to use Z_NO_FLUSH instead of Z_FINISH until you get to your last buff you want to send. Then you use Z_FINISH. Again, take a look at the example and read the comments.

这篇关于C.循环压缩+发送(gzip)ZLIB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆