C.循环压缩+发送(gzip)ZLIB [英] C. Loop compression + send (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数据进行处理。 c $ c>调用。您的代码将丢弃内部循环中生成的压缩数据。在此示例中,在
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屋!