HTTP1.1中CHUNKED编码方式传输数据的解析

“隐网项目”的图片下载模块需要与HTTP Response报文打交道,由于使用的是C++,没有java中十分好用的httpclient,所以打算自己实现。之前考虑的比较简单,假设请求的文件是jpeg文件,所以在收到数据之后,只考虑跳过响应报文的HEADER部分加\r\n\r\n四个字节后,直接把剩余的数据写到文件中。测试过程中,发现有相当一部分图片不能正常打开,总是比服务器多了几个字节;打印输出响应报文后发现头中并没有我们通常所见的Content-Length域来指明报文体的长度,反而是多了Transfer – Encoding域。上网查阅http1.1协议后,发现通常情况下,Transfer-Encoding域的值应当为chunked,表明采用chunked编码方式来进行报文体的传输。协议中关于这个字段的具体解释如下:

一般HTTP通信时会使用是Content-Length头信息来指定body信息大小,但是有时候无法确定信息大小,就要使用trunked编码动态的提供body内容的长度。进行Chunked编码传输的HTTP数据要在消息头部设置:Transfer-Encoding: chunked表示Content Body将用chunked编码传输内容。Chunked编码一般使用若干个chunk串连而成,最后由一个标明长度为0的chunk标示结束。每个chunk分为头部和正文两部分,头部内容指定下一段正文的字符总数(非零开头的十六进制的数字)和数量单位(一般不写,表示字节).正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。在最后一个长度为0的chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。

上述解释过于官方,简而言之,chunked编码的基本方法是将大块数据分解成多块小数据,每块都可以自指定长度,其具体格式如下:

其C语言的解码如下,java思路相同

int nBytes;
char* pStart = a; // a中存放待解码的数据
char* pTemp;
char strlength[10]; //一个chunk块的长度
chunk : pTemp =strstr(pStart,”\r\n”);
if(NULL==pTemp)
{
free(a);
a=NULL;
fclose(fp);
return -1;
}
length=pTemp-pStart;
COPY_STRING(strlength,pStart,length);
pStart=pTemp+2;
nBytes=Hex2Int(strlength); //得到一个块的长度,并转化为十进制

if(nBytes==0)//如果长度为0表明为最后一个chunk
{
free(a);
fclose(fp);
return 0;
}
fwrite(pStart,sizeof(char),nBytes,fp);//将nBytes长度的数据写入文件中
pStart=pStart+nBytes+2; //跳过一个块的数据以及数据之后两个字节的结束符
fflush(fp);
goto chunk; //goto到chunk继续处理

如何将一个十进制数转化为十六进制


char *buf = (char *)malloc(100);
char *d = buf;
int shift = 0;
unsigned long copy = 123445677;
while (copy) {
copy >>= 4;
shift++;
}//首先计算转化为十六进制后的位数
if (shift == 0)
shift++;
shift <<= 2; //将位数乘于4,如果有两位的话 shift为8 while (shift > 0) {
shift -= 4;
*(buf) = hex_chars[(123445677 >> shift) & 0x0F];
buf++;
}
*buf = ‘\0’;

以上内容整理自百度文档:http://wenku.baidu.com/view/50d6f575a417866fb84a8ef9.html
文档未署名,感谢原作者。

几篇关于chunked编码的文章,值得一读:
http://www.redicecn.com/html/qita/20111223/356.html
http://www.httpwatch.com/httpgallery/chunked/
http://www.zeali.net/entry/129

此条目发表在computer分类目录,贴了, 标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据