zlib对http中chunk数据解压
来源:互联网 发布:java 判断日期格式 编辑:程序博客网 时间:2024/05/16 06:03
关键的地方是找到gzip内存的开始位置以及如何确定gzip内容的大小
开始位置:“Content-Encoding: gzip\r\n\r\n”
gzip大小:“Content-Length:”后面的就是了
2 数据包的重组,一般网页的内容很少是一个数据包可以装得下的,所以都得进行gzip之后再用多个数据包进行传输
关键的地方是:
get请求数据包的ack和seq与http返回数据包的ack,seq有密切的联系:
举例说明:
get请求:ack=0,seq=0
http1:seq=0,ack=584
http2: seq=1420,ack=584
...
简单的分析说明可以看出,我们的算法设计:
首先得到get请求的ack,返回的数据包的seq等于这个值,同时记下这个数据包的ack,后面进行分包发送的http的数据包的ack都是这个值,这个是关键点之一,同时综合
Content-Length就可以得到gzip的全部内容。
至此,原始数据提取完毕,该是如何解压的问题了
3解压gzip
我做了上面的1,2步以后将内容保存到文件里面,用gzip命令可以打开,验证了数据的完整性。
而后我采用了zlib提供的uncompress函数,和大多数的网友一样,都是犯了一个致命的错误,没有仔细的阅读zlib的文档!导致一次次无谓的识别!
事实上zlib格式和gzib格式是有差别的,而uncompress是用来解压zlib格式文件的,这就是为什么会出现用compress函数压缩的数据,在内存中可以直接用uncompress函数进行解压的,而就不能解压gzip数据的问题!
后来测试了zlib包里面的example例子,算是对zlib有了一点点的了解,应该用inflate类函数进行解压!
当然这样遇到了问题,格式不对!
后来在网上看到的帖子:gzip格式用inflate函数还不行,必需要用inflateInit2(&strm, 47); !!!!!!!!!!!!!!!!!!
问题解决!
这里借用那位网友的源代码,同时对他表示感谢!
int inflate_read(char *source,int len,char **dest,int gzip)
{
int ret;
unsigned have;
z_stream strm;
unsigned char out[CHUNK];
int totalsize = 0;
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
if(gzip)
ret = inflateInit2(&strm, 47);
else
ret = inflateInit(&strm);
if (ret != Z_OK)
return ret;
strm.avail_in = len;
strm.next_in = source;
/* run inflate() on input until output buffer not full */
do {
strm.avail_out = CHUNK;
strm.next_out = out;
ret = inflate(&strm, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
switch (ret) {
case Z_NEED_DICT:
ret = Z_DATA_ERROR; /* and fall through */
case Z_DATA_ERROR:
case Z_MEM_ERROR:
inflateEnd(&strm);
return ret;
}
have = CHUNK - strm.avail_out;
totalsize += have;
*dest = realloc(*dest,totalsize);
memcpy(*dest + totalsize - have,out,have);
} while (strm.avail_out == 0);
/* clean up and return */
(void)inflateEnd(&strm);
return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
}
感谢Squallxye
下面是我自己做的实验,确实通过了
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include "../include/zlib.h"
#pragma comment(lib,"zdll.lib")
int main(int argc, char* argv[])
{
FILE *comp = fopen("C:\\wode.gz", "rb");
FILE *uncomp = fopen("C:\\wodelog.txt", "wb");
fseek(comp, 0, SEEK_END);
unsigned long complen = ftell(comp);
void *RawDataBuff = malloc(complen);
void *UnCompDataBuff = NULL;
fseek(comp, 0, SEEK_SET);
fread(RawDataBuff, complen , 1, comp);
uLongf UnComplen = complen*4;
UnCompDataBuff = malloc(UnComplen);
int err;
z_stream d_stream;
d_stream.zalloc = (alloc_func)0;
d_stream.zfree = (free_func)0;
d_stream.opaque = (voidpf)0;
d_stream.next_in = (Byte*)RawDataBuff;
d_stream.avail_in = 0;
d_stream.next_out = (Byte*)UnCompDataBuff;
err = inflateInit2(&d_stream,47);
if(err!=Z_OK)
{
printf("inflateInit2 error:%d",err);
return NULL;
}
while (d_stream.total_out < UnComplen && d_stream.total_in < UnComplen) {
d_stream.avail_in = d_stream.avail_out = 1;
err = inflate(&d_stream,Z_NO_FLUSH);
if(err == Z_STREAM_END) break;
if(err!=Z_OK)
{
printf("inflate error:%d",err);
return NULL;
}
}
err = inflateEnd(&d_stream);
if( err != Z_OK )
{
printf( "inflateEnd error:%d" , err );
return NULL;
}
char* b = new char[d_stream.total_out+1];
memset(b,0,d_stream.total_out+1);
memcpy(b,(char*)UnCompDataBuff,d_stream.total_out);
fwrite( b , d_stream.total_out+1, 1, uncomp);
return 0;
}
希望做个笔记,以后别忘了
- zlib对http中chunk数据解压
- 利用zlib库对HTTP收到的gzip数据解压
- 利用zlib库对HTTP收到的gzip数据解压
- Zlib库对网页中deflate压缩数据的解压
- Http chunk方式传输数据
- 用zlib压缩与解压数据
- http chunk
- http chunk
- 在ros中使用zlib解压或者压缩数据该如何配置cmakelists
- 使用zlib库函数实现http报文的解压
- ZLIB quazip (只能对ZIP进行解压,不能对RAR等其它的压缩文件解压)
- 使用zlib实现gzip格式数据的压缩和解压
- [Qt]简单使用 Zlib 库压缩/解压数据
- 使用zlib实现gzip格式数据的压缩和解压
- zlib uncompress解压数据inflate_fast函数出错的解决办法pdf
- zlib uncompress解压数据inflate_fast函数出错的解决办法
- web服务交互中HTTP数据内容GZIP,ZLIB格式压缩与解压缩封装(共享)
- Http协议中关于Content-Length和Chunk
- 内存芯片
- java程序练习-B-流放之路
- Nmap使用举例
- 首届中国跨领域技术交流峰会即将举办
- Delphi中多线程用Synchronize实现VCL数据同步显示 解决在线程中操作控件出现问题
- zlib对http中chunk数据解压
- 我的python学习之路----函数
- JDK1.6(JDK6.0) 新特性
- load_file() MYSQL入侵时查看常用敏感信息文件
- switch中的参数类型
- eclipse 中 ctrl+shift+R 失效的一个原因和解决办法
- zoj 2492 A DP Problem
- 无
- AWE GAE MEGOO 和 提高性能的INTEL的C++重新编译 BigTable是什么东东