HTTP Keep-Alive模式客戶端與服務器是如何判定傳輸完成,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
創(chuàng)新互聯(lián)公司是一家專業(yè)從事網(wǎng)站建設、成都做網(wǎng)站的網(wǎng)絡公司。作為專業(yè)網(wǎng)站建設公司,創(chuàng)新互聯(lián)公司依托的技術實力、以及多年的網(wǎng)站運營經(jīng)驗,為您提供專業(yè)的成都網(wǎng)站建設、全網(wǎng)整合營銷推廣及網(wǎng)站設計開發(fā)服務!
我們知道HTTP協(xié)議采用“請求-應答”模式,當使用普通模式,即非KeepAlive模式時,每個請求/應答客戶和服務器都要新建一個連接,完成 之后立即斷開連接(HTTP協(xié)議為無連接的協(xié)議);當使用Keep-Alive模式(又稱持久連接、連接重用)時,Keep-Alive功能使客戶端到服 務器端的連接持續(xù)有效,當出現(xiàn)對服務器的后繼請求時,Keep-Alive功能避免了建立或者重新建立連接。
Content-Length 是一個實體消息首部,用來指明發(fā)送給接收方的消息主體的大小,即用十進制數(shù)字表示的八位元組的數(shù)目。
在HTTP 1.0 短連接中客戶端發(fā)送一個小請求,服務器響應以所期望的信息(例如一個html文件或一副gif圖像)。服務器通常在發(fā)送回所請求的數(shù)據(jù)之后就關閉連接。這樣客戶端讀數(shù)據(jù)時會返回EOF(-1),就知道數(shù)據(jù)已經(jīng)接收完全了。
消息首部字段Conent-Length
消息首部字段Transfer-Encoding
當客戶端向服務器請求一個靜態(tài)頁面或者一張圖片時,服務器可以很清楚的知道內容大小,然后通過Content-length消息首部字段告訴客戶端需要接收多少數(shù)據(jù)。但是如果是動態(tài)頁面等時,服務器是不可能預先知道內容大小,這時就可以使用Transfer-Encoding:chunk模式來傳輸數(shù)據(jù)了。即如果要一邊產(chǎn)生數(shù)據(jù),一邊發(fā)給客戶端,服務器就需要使用"Transfer-Encoding: chunked"這樣的方式來代替Content-Length。
chunk編碼將數(shù)據(jù)分成一塊一塊的發(fā)生。Chunked編碼將使用若干個Chunk串連而成,由一個標明長度為0的chunk標示結束。每個Chunk分為頭部和正文兩部分,頭部內容指定正文的字符總數(shù)(十六進制的數(shù)字)和數(shù)量單位(一般不寫),正文部分就是指定長度的實際內容,兩部分之間用回車換行(CRLF)隔開。在最后一個長度為0的Chunk中的內容是稱為footer的內容,是一些附加的Header信息(通常可以直接忽略)。
Transfer-Encoding 是一個用來標示 HTTP 報文傳輸格式的頭部值。盡管這個取值理論上可以有很多,但是當前的 HTTP 規(guī)范里實際上只定義了一種傳輸取值——chunked。
如果一個HTTP消息(請求消息或應答消息)的Transfer-Encoding消息頭的值為chunked,那么,消息體由數(shù)量未定的塊組成,并以最后一個大小為0的塊為結束。
每一個非空的塊都以該塊包含數(shù)據(jù)的字節(jié)數(shù)(字節(jié)數(shù)以十六進制表示)開始,跟隨一個CRLF (回車及換行),然后是數(shù)據(jù)本身,最后塊CRLF結束。在一些實現(xiàn)中,塊大小和CRLF之間填充有白空格(0x20)。
最后一塊是單行,由塊大小(0),一些可選的填充白空格,以及CRLF。最后一塊不再包含任何數(shù)據(jù),但是可以發(fā)送可選的尾部,包括消息頭字段。消息最后以CRLF結尾。
一個示例響應如下:
HTTP/1.1 200 OKContent-Type: text/plainTransfer-Encoding: chunked25This is the data in the first chunk1A and this is the second one0
注意:
chunked 和 multipart 兩個名詞在意義上有類似的地方,不過在 HTTP 協(xié)議當中這兩個概念則不是一個類別的。multipart 是一種 Content-Type,標示 HTTP 報文內容的類型,而 chunked 是一種傳輸格式,標示報頭將以何種方式進行傳輸。
chunked 傳輸不能事先知道內容的長度,只能靠最后的空 chunk 塊來判斷,因此對于下載請求來說,是沒有辦法實現(xiàn)進度的。在瀏覽器和下載工具中,偶爾我們也會看到有些文件是看不到下載進度的,即采用 chunked 方式進行下載。
chunked 的優(yōu)勢在于,服務器端可以邊生成內容邊發(fā)送,無需事先生成全部的內容。HTTP/2 不支持 instagram user search Transfer-Encoding: chunked,因為 HTTP/2 有自己的 streaming 傳輸方式(Source:MDN - Transfer-Encoding)。
其實,上面2中方法都可以歸納為是如何判斷http消息的大小、消息的數(shù)量。RFC 2616對消息的長度總結如下:一個消息的transfer-length(傳輸長度)是指消息中的message-body(消息體)的長度。當應用了transfer-coding(傳輸編碼),每個消息中的message-body(消息體)的長度(transfer-length)由以下幾種情況決定(優(yōu)先級由高到低):
任何不含有消息體的消息(如1XXX、204、304等響應消息和任何頭(HEAD,首部)請求的響應消息),總是由一個空行(CLRF)結束。
如果出現(xiàn)了Transfer-Encoding頭字段 并且值為非“identity”,那么transfer-length由“chunked” 傳輸編碼定義,除非消息由于關閉連接而終止。
如果出現(xiàn)了Content-Length頭字段,它的值表示entity-length(實體長度)和transfer-length(傳輸長度)。如果這兩個長度的大小不一樣(i.e.設置了Transfer-Encoding頭字段),那么將不能發(fā)送Content-Length頭字段。并且如果同時收到了Transfer-Encoding字段和Content-Length頭字段,那么必須忽略Content-Length字段。
如果消息使用媒體類型“multipart/byteranges”,并且transfer-length 沒有另外指定,那么這種自定界(self-delimiting)媒體類型定義transfer-length 。除非發(fā)送者知道接收者能夠解析該類型,否則不能使用該類型。
由服務器關閉連接確定消息長度。(注意:關閉連接不能用于確定請求消息的結束,因為服務器不能再發(fā)響應消息給客戶端了。)
為了兼容HTTP/1.0應用程序,HTTP/1.1的請求消息體中必須包含一個合法的Content-Length頭字段,除非知道服務器兼容HTTP/1.1。一個請求包含消息體,并且Content-Length字段沒有給定,如果不能判斷消息的長度,服務器應該用用400 (bad request) 來響應;或者服務器堅持希望收到一個合法的Content-Length字段,用 411 (length required)來響應。
所有HTTP/1.1的接收者應用程序必須接受“chunked” transfer-coding (傳輸編碼),因此當不能事先知道消息的長度,允許使用這種機制來傳輸消息。消息不應該夠同時包含 Content-Length頭字段和non-identity transfer-coding。如果一個消息同時包含non-identity transfer-coding和Content-Length ,必須忽略Content-Length 。
關于HTTP Keep-Alive模式客戶端與服務器是如何判定傳輸完成問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關知識。