溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

HTTP Keep-Alive模式客戶端與服務(wù)器是如何判定傳輸完成

發(fā)布時(shí)間:2021-12-22 14:57:56 來(lái)源:億速云 閱讀:218 作者:柒染 欄目:云計(jì)算

HTTP Keep-Alive模式客戶端與服務(wù)器是如何判定傳輸完成,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

長(zhǎng)連接是什么

我們知道HTTP協(xié)議采用“請(qǐng)求-應(yīng)答”模式,當(dāng)使用普通模式,即非KeepAlive模式時(shí),每個(gè)請(qǐng)求/應(yīng)答客戶和服務(wù)器都要新建一個(gè)連接,完成 之后立即斷開(kāi)連接(HTTP協(xié)議為無(wú)連接的協(xié)議);當(dāng)使用Keep-Alive模式(又稱(chēng)持久連接、連接重用)時(shí),Keep-Alive功能使客戶端到服 務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對(duì)服務(wù)器的后繼請(qǐng)求時(shí),Keep-Alive功能避免了建立或者重新建立連接。

服務(wù)器如何知道已經(jīng)完全接受客戶端發(fā)送的數(shù)據(jù)

Content-Length 是一個(gè)實(shí)體消息首部,用來(lái)指明發(fā)送給接收方的消息主體的大小,即用十進(jìn)制數(shù)字表示的八位元組的數(shù)目。

客戶端如何知道已經(jīng)完全接受服務(wù)端發(fā)送的數(shù)據(jù)

  • 在HTTP 1.0 短連接中客戶端發(fā)送一個(gè)小請(qǐng)求,服務(wù)器響應(yīng)以所期望的信息(例如一個(gè)html文件或一副gif圖像)。服務(wù)器通常在發(fā)送回所請(qǐng)求的數(shù)據(jù)之后就關(guān)閉連接。這樣客戶端讀數(shù)據(jù)時(shí)會(huì)返回EOF(-1),就知道數(shù)據(jù)已經(jīng)接收完全了。

  • 消息首部字段Conent-Length

  • 消息首部字段Transfer-Encoding

Transfer-Encoding

當(dāng)客戶端向服務(wù)器請(qǐng)求一個(gè)靜態(tài)頁(yè)面或者一張圖片時(shí),服務(wù)器可以很清楚的知道內(nèi)容大小,然后通過(guò)Content-length消息首部字段告訴客戶端需要接收多少數(shù)據(jù)。但是如果是動(dòng)態(tài)頁(yè)面等時(shí),服務(wù)器是不可能預(yù)先知道內(nèi)容大小,這時(shí)就可以使用Transfer-Encoding:chunk模式來(lái)傳輸數(shù)據(jù)了。即如果要一邊產(chǎn)生數(shù)據(jù),一邊發(fā)給客戶端,服務(wù)器就需要使用"Transfer-Encoding: chunked"這樣的方式來(lái)代替Content-Length。

chunk編碼將數(shù)據(jù)分成一塊一塊的發(fā)生。Chunked編碼將使用若干個(gè)Chunk串連而成,由一個(gè)標(biāo)明長(zhǎng)度為0的chunk標(biāo)示結(jié)束。每個(gè)Chunk分為頭部和正文兩部分,頭部?jī)?nèi)容指定正文的字符總數(shù)(十六進(jìn)制的數(shù)字)和數(shù)量單位(一般不寫(xiě)),正文部分就是指定長(zhǎng)度的實(shí)際內(nèi)容,兩部分之間用回車(chē)換行(CRLF)隔開(kāi)。在最后一個(gè)長(zhǎng)度為0的Chunk中的內(nèi)容是稱(chēng)為footer的內(nèi)容,是一些附加的Header信息(通??梢灾苯雍雎裕?。

Transfer-Encoding 是一個(gè)用來(lái)標(biāo)示 HTTP 報(bào)文傳輸格式的頭部值。盡管這個(gè)取值理論上可以有很多,但是當(dāng)前的 HTTP 規(guī)范里實(shí)際上只定義了一種傳輸取值——chunked。

如果一個(gè)HTTP消息(請(qǐng)求消息或應(yīng)答消息)的Transfer-Encoding消息頭的值為chunked,那么,消息體由數(shù)量未定的塊組成,并以最后一個(gè)大小為0的塊為結(jié)束。

每一個(gè)非空的塊都以該塊包含數(shù)據(jù)的字節(jié)數(shù)(字節(jié)數(shù)以十六進(jìn)制表示)開(kāi)始,跟隨一個(gè)CRLF (回車(chē)及換行),然后是數(shù)據(jù)本身,最后塊CRLF結(jié)束。在一些實(shí)現(xiàn)中,塊大小和CRLF之間填充有白空格(0x20)。

最后一塊是單行,由塊大?。?),一些可選的填充白空格,以及CRLF。最后一塊不再包含任何數(shù)據(jù),但是可以發(fā)送可選的尾部,包括消息頭字段。消息最后以CRLF結(jié)尾。

一個(gè)示例響應(yīng)如下:

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 兩個(gè)名詞在意義上有類(lèi)似的地方,不過(guò)在 HTTP 協(xié)議當(dāng)中這兩個(gè)概念則不是一個(gè)類(lèi)別的。multipart 是一種 Content-Type,標(biāo)示 HTTP 報(bào)文內(nèi)容的類(lèi)型,而 chunked 是一種傳輸格式,標(biāo)示報(bào)頭將以何種方式進(jìn)行傳輸。

  • chunked 傳輸不能事先知道內(nèi)容的長(zhǎng)度,只能靠最后的空 chunk 塊來(lái)判斷,因此對(duì)于下載請(qǐng)求來(lái)說(shuō),是沒(méi)有辦法實(shí)現(xiàn)進(jìn)度的。在瀏覽器和下載工具中,偶爾我們也會(huì)看到有些文件是看不到下載進(jìn)度的,即采用 chunked 方式進(jìn)行下載。

  • chunked 的優(yōu)勢(shì)在于,服務(wù)器端可以邊生成內(nèi)容邊發(fā)送,無(wú)需事先生成全部的內(nèi)容。HTTP/2 不支持 instagram user search Transfer-Encoding: chunked,因?yàn)?HTTP/2 有自己的 streaming 傳輸方式(Source:MDN - Transfer-Encoding)。

transfer-coding與Content-Length

其實(shí),上面2中方法都可以歸納為是如何判斷http消息的大小、消息的數(shù)量。RFC 2616對(duì)消息的長(zhǎng)度總結(jié)如下:一個(gè)消息的transfer-length(傳輸長(zhǎng)度)是指消息中的message-body(消息體)的長(zhǎng)度。當(dāng)應(yīng)用了transfer-coding(傳輸編碼),每個(gè)消息中的message-body(消息體)的長(zhǎng)度(transfer-length)由以下幾種情況決定(優(yōu)先級(jí)由高到低):

  • 任何不含有消息體的消息(如1XXX、204、304等響應(yīng)消息和任何頭(HEAD,首部)請(qǐng)求的響應(yīng)消息),總是由一個(gè)空行(CLRF)結(jié)束。

  • 如果出現(xiàn)了Transfer-Encoding頭字段 并且值為非“identity”,那么transfer-length由“chunked” 傳輸編碼定義,除非消息由于關(guān)閉連接而終止。

  • 如果出現(xiàn)了Content-Length頭字段,它的值表示entity-length(實(shí)體長(zhǎng)度)和transfer-length(傳輸長(zhǎng)度)。如果這兩個(gè)長(zhǎng)度的大小不一樣(i.e.設(shè)置了Transfer-Encoding頭字段),那么將不能發(fā)送Content-Length頭字段。并且如果同時(shí)收到了Transfer-Encoding字段和Content-Length頭字段,那么必須忽略Content-Length字段。

  • 如果消息使用媒體類(lèi)型“multipart/byteranges”,并且transfer-length 沒(méi)有另外指定,那么這種自定界(self-delimiting)媒體類(lèi)型定義transfer-length 。除非發(fā)送者知道接收者能夠解析該類(lèi)型,否則不能使用該類(lèi)型。

  • 由服務(wù)器關(guān)閉連接確定消息長(zhǎng)度。(注意:關(guān)閉連接不能用于確定請(qǐng)求消息的結(jié)束,因?yàn)榉?wù)器不能再發(fā)響應(yīng)消息給客戶端了。)

為了兼容HTTP/1.0應(yīng)用程序,HTTP/1.1的請(qǐng)求消息體中必須包含一個(gè)合法的Content-Length頭字段,除非知道服務(wù)器兼容HTTP/1.1。一個(gè)請(qǐng)求包含消息體,并且Content-Length字段沒(méi)有給定,如果不能判斷消息的長(zhǎng)度,服務(wù)器應(yīng)該用用400 (bad request) 來(lái)響應(yīng);或者服務(wù)器堅(jiān)持希望收到一個(gè)合法的Content-Length字段,用 411 (length required)來(lái)響應(yīng)。

所有HTTP/1.1的接收者應(yīng)用程序必須接受“chunked” transfer-coding (傳輸編碼),因此當(dāng)不能事先知道消息的長(zhǎng)度,允許使用這種機(jī)制來(lái)傳輸消息。消息不應(yīng)該夠同時(shí)包含 Content-Length頭字段和non-identity transfer-coding。如果一個(gè)消息同時(shí)包含non-identity transfer-coding和Content-Length ,必須忽略Content-Length 。

關(guān)于HTTP Keep-Alive模式客戶端與服務(wù)器是如何判定傳輸完成問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI