HTTP1.1协议的chunked编码(chunked transfer encoding分块传输编码)

一般情况HTTP的Header包含Content-Length域来指明报文体的长度。

有时候服务生成HTTP回应是无法确定消息大小的,比如大文件的下载,或者后台需要复杂的逻辑才能全部处理页面的请求,这时用需要实时生成消息长度,服务器一般使用chunked编码。采用chunked编码有两种选择,一种是设定Server的IO buffer长度让Server自动flush buffer中的内容,另一种是手动调用IO中的flush函数。不同的语言IO中都有flush功能:
 - php: ob_flush(); flush();
 - perl: STDOUT->autoflush(1);
 - java: out.flush();
 - python: sys.stdout.flush()
  - ruby: stdout.flush

使用chunked编码的Headers如下(可以利用FireFox的FireBug插件或HttpWatch查看Headers信息,HttpWatch还可以查看chunked的个数):

HTTP1.1协议的chunked编码(chunked transfer encoding分块传输编码)_第1张图片

Chunked编码一般使用若干个chunk串连而成,最后由一个标明长度为0的chunk标示结束。每个chunk分为头部和正文两部分,头部内容指定下一段正文的字符总数(非零开头的十六进制的数字)和数量单位(一般不写,表示字节).正文部分就是指定长度的实际内容,两部分之间用回车换行(CRLF)隔开。在最后一个长度为0的chunk中的内容是称为footer的内容,是一些附加的Header信息(通常可以直接忽略)。


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

Chunked-Body   = *chunk            //0至多个chunk
		last-chunk         //最后一个chunk
		trailer            //尾部
		CRLF               //结束标记符
chunk          = chunk-size [ chunk-extension ] CRLF
		chunk-data CRLF
chunk-size     = 1*HEX
last-chunk     = 1*("0") [ chunk-extension ] CRLF
chunk-extension= *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
chunk-ext-name = token
chunk-ext-val  = token | quoted-string
chunk-data     = chunk-size(OCTET)
trailer        = *(entity-header CRLF)





解释:
Chunked-Body表示经过chunked编码后的报文体。报文体可以分为chunk, last-chunk,trailer和结束符四部分。chunk的数量在报文体中最少可以为0,无上限;

每个chunk的长度是自指定的,即,起始的数据必然是16进制数字的字符串,代表后面chunk-data的长度(字节数)。这个16进制的字符串第一个字符如果是“0”,则表示chunk-size为0,该chunk为last-chunk,无chunk-data部分。

可选的chunk-extension由通信双方自行确定,如果接收者不理解它的意义,可以忽略。

trailer是附加的在尾部的额外头域,通常包含一些元数据(metadata, meta means "about information"),这些头域可以在解码后附加在现有头域之后

HTTP1.1协议的chunked编码(chunked transfer encoding分块传输编码)_第2张图片

看一个wireshark抓包的结果:

HTTP1.1协议的chunked编码(chunked transfer encoding分块传输编码)_第3张图片

这里面只有一个有意义的chunke以及一个footer。第一个chunk,头部是3134这两个字节,表示的是1和4这两个ascii字符,被http协议解释为十六进制数14,也就是十进制的20。后面紧跟0d0a,再接着是20个字节的chunk正文(图中的011e~0131)。

后面再接着0d0a,然后就是footer了,30表示ascii字符0,http解释为长度是0(也说明了这是最后一个chunk),后面紧跟0d0a,然后正文部分为空,再接0d 0a表示结束


转载文章:

1)http://blog.csdn.net/zhangboyj/article/details/6236780

2)http://www.cnblogs.com/jhxk/articles/2715848.html

3)http://www.cnblogs.com/jhxk/articles/2715848.html

你可能感兴趣的:(Web开发)