我想知道zlib是否可以解压流数据。
例如gzip文件被分成三个TCP段(overlay为http)进行传输。我可以分别解压第一、第二、第三个tcp段来获取原始数据吗?
我的测试结论是只有收到完整的gzip文件后才能正确解压。
int http_content_decompress_write_zlib(struct http_content_decompress *decompress,
const char *indata, size_t indata_len,
char **outdata, size_t *outdata_len) {
z_stream *z_stream_ptr = decompress->z_stream_ptr;
z_stream_ptr->avail_in = (unsigned int)indata_len;
z_stream_ptr->next_in = (unsigned char *)indata;
*outdata = NULL;
*outdata_len = 0;
int ret = 0;
do {
z_stream_ptr->avail_out = (unsigned int)decompress->buffer_size;
z_stream_ptr->next_out = (unsigned char *)decompress->buffer;
ret = inflate(z_stream_ptr, Z_NO_FLUSH);
if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT
|| ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) {
printf("error msg:%s\n", z_stream_ptr->msg);
//(void)inflateEnd(z_stream_ptr);
//return -1;
}
size_t have = decompress->buffer_size - z_stream_ptr->avail_out;
if (have > 0) {
if (NULL == *outdata) {
http_decoder_log(DEBUG, "%s alloc outbuffer %zu bytes",
http_content_encoding_int2str(decompress->encoding),
have);
*outdata = safe_dup(decompress->buffer, have);
*outdata_len = have;
} else {
http_decoder_log(DEBUG, "%s realloc outbuffer %zu bytes",
http_content_encoding_int2str(decompress->encoding),
*outdata_len + have + 1);
*outdata = REALLOC(char, *outdata, *outdata_len + have + 1);
memcpy(*outdata + *outdata_len, decompress->buffer, have);
*outdata_len = *outdata_len + have;
memset(*outdata + *outdata_len, 0, 1);
}
} else {
}
} while (0 == z_stream_ptr->avail_out);
return 0;
}
Zlib 专为流媒体而设计。它会解压缩第一个段,并在其他数据到达之前从该段获取所有未压缩的数据。然后继续解压第二段。然后是第三个。
具体来说,在第一个段解压完成之前,zlib 无法解压第二个段。 tcp 段必须按顺序解压缩。 @Mark Adler [电子邮件受保护]
问题原因是我重复创建zlib解压句柄。