網(wǎng)上使用Chunked編碼的網(wǎng)站似乎并不是很多,除了那些使用GZip壓縮的網(wǎng)站,例:google.com,還有就是大部分打開GZip壓縮的PHP論壇。
根據(jù)本人的理解,使用Chunked編碼的主要好處就在于一些程序的運(yùn)算出過程中,可以動(dòng)態(tài)的輸出內(nèi)容。
例如,要在后臺(tái)處理一個(gè)小時(shí)的運(yùn)算,但又不希望用戶等一個(gè)小時(shí)才能看到結(jié)果。這時(shí)就可采用Chunked編碼將內(nèi)容分塊輸出,用戶隨時(shí)都可以接收到最新的處理結(jié)果。
ASP關(guān)閉了緩存的輸出模式,就是Chunked編碼的。(Response.Buffer = false)
而每一次的Response.Write,都是一個(gè)Chunked,所以不要使用的太頻繁哦,否則Chunk數(shù)量太多,額外的數(shù)據(jù)太浪費(fèi)空間了。
若想了解Chunked的具體編碼結(jié)構(gòu),用ASP關(guān)閉緩存調(diào)試蠻方便的。:)
我們先來看看RFC2616中對(duì)Chunked的定義:
Chunked-Body = *chunk
last-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)
我們來模擬一下數(shù)據(jù)結(jié)構(gòu):
[Chunk大小][回車][Chunk數(shù)據(jù)體][回車][Chunk大小][回車][Chunk數(shù)據(jù)體][回車][0][回車]
注意chunk-size是以十六進(jìn)制的ASCII碼表示的,比如86AE(實(shí)際的十六進(jìn)制應(yīng)該是:38366165),計(jì)算成長(zhǎng)度應(yīng)該是:34478,表示從回車之后有連續(xù)的34478字節(jié)的數(shù)據(jù)。
跟蹤了的返回?cái)?shù)據(jù),發(fā)現(xiàn)在chunk-size中,還會(huì)多一些空格。可能是固定長(zhǎng)度為7個(gè)字節(jié),不滿7個(gè)字節(jié)的,就以空格補(bǔ)足,空格的ASCII碼是0x20。
以下是解碼過程的偽代碼:
length := 0//用來記錄解碼后的數(shù)據(jù)體長(zhǎng)度
read chunk-size, chunk-extension (if any) and CRLF//第一次讀取塊大小
while (chunk-size > 0) {//一直循環(huán),直到讀取的塊大小為0
read chunk-data and CRLF//讀取塊數(shù)據(jù)體,以回車結(jié)束
append chunk-data to entity-body//添加塊數(shù)據(jù)體到解碼后實(shí)體數(shù)據(jù)
length := length + chunk-size//更新解碼后的實(shí)體長(zhǎng)度
read chunk-size and CRLF//讀取新的塊大小
}
read entity-header//以下代碼讀取全部的頭標(biāo)記
while (entity-header not empty) {
append entity-header to existing header fields
read entity-header
}
Content-Length := length//頭標(biāo)記中添加內(nèi)容長(zhǎng)度
Remove "chunked" from Transfer-Encoding//頭標(biāo)記中移除Transfer-Encoding
有空再研究一下GZip+Chunked是如何編碼的,估計(jì)是每個(gè)Chunk塊進(jìn)行一次GZip獨(dú)立壓縮。
使用了Chunked,自然會(huì)在性能上稍微打點(diǎn)折扣,因?yàn)楸日5臄?shù)據(jù)體多出了一些額外的消耗。
但是有一些情況下,必需要使用分塊輸出,這也是不得已而為之.
更多信息請(qǐng)查看IT技術(shù)專欄