1. 程式人生 > >HTTP1.1協議的chunked編碼(chunked transfer encoding分塊傳輸編碼)

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的個數):



Chunked編碼一般使用若干個chunk串連而成,最後由一個標明長度為0的chunk標示結束。每個chunk分為頭部和正文兩部分,頭部內容指定下一段正文的字元總數(非零開頭的十六進位制的數字)和數量單位(一般不寫,表示位元組).正文部分就是指定長度的實際內容,兩部分之間用回車換行(CRLF)隔開。在最後一個長度為0的chunk中的內容是稱為footer的內容,是一些附加的Header資訊(通常可以直接忽略)。

上述解釋過於官方,簡而言之,chunked編碼的基本方法是將大塊資料分解成多塊小資料,每塊都可以自指定長度,其具體格式如下(BNF文法):

<pre name="code" class="java">Chunked-Body   = *chunk            //0至多個chunk
<span style="white-space:pre">		</span>last-chunk         //最後一個chunk
<span style="white-space:pre">		</span>trailer            //尾部
<span style="white-space:pre">		</span>CRLF               //結束標記符
chunk          = chunk-size [ chunk-extension ] CRLF
<span style="white-space:pre">		</span>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"),這些頭域可以在解碼後附加在現有頭域之後


看一個wireshark抓包的結果:


這裡面只有一個有意義的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