C.循环压缩+;发送(gzip)ZLIB

C.循环压缩+;发送(gzip)ZLIB,c,http,compression,gzip,zlib,C,Http,Compression,Gzip,Zlib,我目前正在用C构建一个HTTP服务器 请记住这段代码: #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;

我目前正在用C构建一个HTTP服务器

请记住这段代码:

  #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缓冲区(当它们被连接时),这是一个整体请求

但是:目前,我的客户机(浏览器)只获取第一个缓冲区的信息。不过,一点错误也没有


如何实现这项工作,如何在循环中gzip一些缓冲区,以便每次(在循环中)发送它们?

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

        have = CHUNK - strm.avail_out;
        if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
            (void)deflateEnd(&strm);
            return Z_ERRNO;
        }
这就是您的
send_to_client
需要的位置,发送
时需要有
字节

在您的例子中,您的
比您的
buff
大得多,循环总是只执行一次,因此您不会丢弃任何数据。但是,这只是因为
Z_FINISH
,所以当您进行下一次修复时,您将使用当前代码丢弃数据

第二,每次输入不超过199字节,就完成了
deflate()
流。这将极大地限制您可以获得的压缩量。此外,您正在发送单独的gzip流,对于这些流,大多数浏览器将只解释第一个。(这实际上是这些浏览器中的一个bug,但我不认为它们会被修复。)


您需要为压缩器提供至少10到100千字节的工作空间,以便获得适当的压缩。您需要使用
Z_NO_FLUSH
而不是
Z_FINISH
,直到到达要发送的最后一个
buff
。然后使用
Z_FINISH
。再次,看一看示例并阅读注释。

好的,这回答了我的问题。我真的很感激你的回答。非常感谢你的帮助。