HTTP 1 1組塊(chunked)傳輸編碼實驗

2021-09-08 20:46:18 字數 3500 閱讀 2141

http/1.1組塊(chunked)傳輸編碼實驗_redice's blog

美國、日本極速穩定免備案主機,支援月付,即刻開通,7×24小時技術支援.

拿到了盜版的 web協議與實踐(http1.1、網路協議、快取技術和流量檢測)。這本書的正版現在已經買不到了,京東上有這本書,但是也是無貨,標價竟然只有33.8元,說實話這個**連成本都不夠。

後來花了90塊錢從**買了盜版,書的印刷質量真的不咋樣,很多地方都很模糊。不過的確是好書,這是我讀過的第一本把http協議講的很透徹的書(這方面的書本身就不過,之前我看的最多的就是

rfc2616)。

pdf版我也拿到了,想要的發郵件吧。

進入正題。

http是如何確保參與各方(通常是瀏覽器和web伺服器)認識到它們已經接收到了完整的訊息?

實體的長度是乙個重要的指示符,接收方據此可知道何時收到了完整的實體。http/1.0可用來指定實體長度的唯一機制是通過content-length欄位。靜態資源的長度可以很容易地確定;但是對於動態生成的響應來說(比如在 phpmyadmin中匯出資料庫的操作,資料的大小是事先不能確定的),為獲取它的真實長度,只能等它完全生成之後,才能正確地填寫content-length的值,這便要求快取整個響應,從而增大了終端使用者的延遲。在http/1.0中,伺服器可以通過關閉連線來指示動態內容的結尾,如果關閉連線是指示動態響應結尾的唯一辦法,那麼http/1.1的持久連線便不可能實現了(tcp鏈結復用、持久化連線是http/1.1的乙個重大改進,它可以提高頻寬的利用率)。

為了解決這個問題,http/1.1引入了被稱為組塊(chunked)的傳輸編碼方法。該方法使傳送方能將訊息實體分割為任意大小的組塊(chunk),並單獨地傳送他們。在每個組塊前面,都加上了該組塊的長度,使接收方可確保自己能夠完整地接收到這個組塊。更重要的是,在最末尾的地方,傳送方生成了長度為零的組塊。接收方可據此判斷整條訊息都已安全地傳輸完畢。這樣也避免了在伺服器端占用大量的快取。transfer-encoding標頭(值為chunked)向接收方指出:響應將被分組塊,對響應分析時,應採取不同於非分組塊的影響方式。

上面是我對,web協議與實踐7.6節「訊息傳輸」的概括。

下面是兩個實驗:

測試環境: apache + php。

測試指令碼如下:

獲取的。

它讀取伺服器的乙個檔案,然後動態地輸出該檔案的資料(每隔1s輸出一定長度的資料)。

view plain

copy to clipboard

print

?

<?php   

set_time_limit(0);  

// send the contents of the topmost output buffer (if any) and turn this output buffer off

ob_end_flush();  

// local file that should be send to the client

$local_file = 'test.bin';  

// filename that the user gets as default

$download_file = $local_file;  

// set the download rate limit (=--> 10 kb/s)

$download_rate = 10;  

if(file_exists($local_file) && is_file($local_file))   

// close file stream

fclose($file);  

}  else   

?>   

<?php 

set_time_limit(0);

// send the contents of the topmost output buffer (if any) and turn this output buffer off

ob_end_flush();

// local file that should be send to the client

$local_file = 'test.bin';

// filename that the user gets as default

$download_file = $local_file;

// set the download rate limit (=--> 10 kb/s)

$download_rate = 10;

if(file_exists($local_file) && is_file($local_file))

// close file stream

fclose($file);

}else

?>

ob_end_flush()將確保指令碼執行過程中不使用快取,這意味著任何輸出的資料都將立即被傳送到客戶端。

1)帶content-length的響應。

如上述**,在應答頭中我們手動新增了content-length欄位(該值由檔案的實際大小決定)。

我們可以看到應答頭中包含了content-length標頭字段。

2)不帶content-length的響應。

將上述**中的header('content-length: '.filesize($local_file));語句注釋掉。

在應答頭中我們可以看到transfer-encoding: chunked,說明這次伺服器使用了組塊式的應答。

特別說明:經過測試發現「iis + isapi php」不支援關閉程式執行過程中的快取(flush(), ob_implicit_flush(true), ob_end_flush()均不起作用)。

注意本文所說的快取都指的是php直譯器在執行php**過程中使用的記憶體快取區(變數),而不是伺服器或客戶端的檔案快取。

所以如果在「iis + isapi php」環境下做實驗二,伺服器總是會將資料先放到快取中直到程式執行完畢,得到content-length值後,傳送非chunked的應答。

view plain

copy to clipboard

print

?

<?php   

ob_end_flush();  

for ($i=0; $i

<5; $i++)   

?>   

<?php 

ob_end_flush();

for ($i=0; $i<5; $i++)

?>

上述**在apache伺服器中部署,在瀏覽器中訪問看到的情況會是0到4的數字每隔1s輸出乙個,但是在「iis + isapi php」環境下始終是5個數字一起輸出的。

同時我看到了有網友表示在"nginx + fast cgi php"環境下,php的程式快取控制也會失敗,看這裡。

http1 1簡要介紹

說到網路協議,自然就讓人聯想到http了,而這也是我要用到的。所以我還是規規矩矩,先讀一讀http1.1的協議書.http1.1協議書有176頁,要把所有問題都搞明白也不是一時半會兒的問題。對於我來講,也沒有這個必要。所以,只要掌握一些基本的概念,能用起來就行。http協議是tcp ip應用層協議。...

HTTP1 1 請求方法小記

根據http標準,http請求可以使用多種請求方法。http1.0定義了三種請求方法 get,post 和 head方法。http1.1新增了五種請求方法 options,put,delete,trace 和 connect 方法。注意 方法名稱區分大小寫 1 options 返回伺服器針對特定資源...

HTTP1 1 幾種方法

get 方法用來請求訪問已被 uri 識別的資源post 方法用來傳輸實體的主體。雖然用 get 方法也可以傳輸實體的主體,但一般不用 get 方法進行傳輸,而是用 post 方法 雖說 post 的功能與 get 很相似,但 post 的主要目的並不是獲取響應的主體內容put 方法用來傳輸檔案.h...