Keep-Alive模式
生活随笔
收集整理的這篇文章主要介紹了
Keep-Alive模式
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
轉(zhuǎn)自:http://www.lirang.net/post/24.html
1、什么是Keep-Alive模式?
我們知道HTTP協(xié)議采用“請求-應(yīng)答”模式,當(dāng)使用普通模式,即非KeepAlive模式時(shí),每個(gè)請求/應(yīng)答客戶和服務(wù)器都要新建一個(gè)連接,完成 之后立即斷開連接(HTTP協(xié)議為無連接的協(xié)議);當(dāng)使用Keep-Alive模式(又稱持久連接、連接重用)時(shí),Keep-Alive功能使客戶端到服 務(wù)器端的連接持續(xù)有效,當(dāng)出現(xiàn)對服務(wù)器的后繼請求時(shí),Keep-Alive功能避免了建立或者重新建立連接。 http 1.0中默認(rèn)是關(guān)閉的,需要在http頭加入"Connection: Keep-Alive",才能啟用Keep-Alive;http 1.1中默認(rèn)啟用Keep-Alive,如果加入"Connection: close ",才關(guān)閉。目前大部分瀏覽器都是用http1.1協(xié)議,也就是說默認(rèn)都會發(fā)起Keep-Alive的連接請求了,所以是否能完成一個(gè)完整的Keep- Alive連接就看服務(wù)器設(shè)置情況。 2、啟用Keep-Alive的優(yōu)點(diǎn) 從上面的分析來看,啟用Keep-Alive模式肯定更高效,性能更高。因?yàn)楸苊饬私?釋放連接的開銷。下面是RFC 2616 上的總結(jié): By opening and closing fewer TCP connections, CPU time is saved in routers and hosts (clients, servers, proxies, gateways, tunnels, or caches), and memory used for TCP protocol control blocks can be saved in hosts. HTTP requests and responses can be pipelined on a connection. Pipelining allows a client to make multiple requests without waiting for each response, allowing a single TCP connection to be used much more efficiently, with much lower elapsed time. Network congestion is reduced by reducing the number of packets caused by TCP opens, and by allowing TCP sufficient time to determine the congestion state of the network. Latency on subsequent requests is reduced since there is no time spent in TCP's connection opening handshake. HTTP can evolve more gracefully, since errors can be reported without the penalty of closing the TCP connection. Clients using ? ? future versions of HTTP might optimistically try a new feature, but if communicating with an older server, retry with old ? semantics after an error is reported. RFC 2616 (P47) 還指出:單用戶客戶端與任何服務(wù)器或代理之間的連接數(shù)不應(yīng)該超過2個(gè)。一個(gè)代理與其它服務(wù)器或代碼之間應(yīng)該使用超過2 * N的活躍并發(fā)連接。這是為了提高HTTP響應(yīng)時(shí)間,避免擁塞(冗余的連接并不能代碼執(zhí)行性能的提升)。 3、回到我們的問題(即如何判斷消息內(nèi)容/長度的大小?) Keep-Alive模式,客戶端如何判斷請求所得到的響應(yīng)數(shù)據(jù)已經(jīng)接收完成(或者說如何知道服務(wù)器已經(jīng)發(fā)生完了數(shù)據(jù))?我們已經(jīng)知道 了,Keep-Alive模式發(fā)送玩數(shù)據(jù)HTTP服務(wù)器不會自動(dòng)斷開連接,所有不能再使用返回EOF(-1)來判斷(當(dāng)然你一定要這樣使用也沒有辦法,可 以想象那效率是何等的低)!下面我介紹兩種來判斷方法。 3.1、使用消息首部字段Conent-Length 故名思意,Conent-Length表示實(shí)體內(nèi)容長度,客戶端(服務(wù)器)可以根據(jù)這個(gè)值來判斷數(shù)據(jù)是否接收完成。但是如果消息中沒有Conent-Length,那該如何來判斷呢?又在什么情況下會沒有Conent-Length呢?請繼續(xù)往下看…… 3.2、使用消息首部字段Transfer-Encoding 當(dāng)客戶端向服務(wù)器請求一個(gè)靜態(tài)頁面或者一張圖片時(shí),服務(wù)器可以很清楚的知道內(nèi)容大小,然后通過Content-length消息首部字段告訴客戶端 需要接收多少數(shù)據(jù)。但是如果是動(dòng)態(tài)頁面等時(shí),服務(wù)器是不可能預(yù)先知道內(nèi)容大小,這時(shí)就可以使用Transfer-Encoding:chunk模式來傳輸 數(shù)據(jù)了。即如果要一邊產(chǎn)生數(shù)據(jù),一邊發(fā)給客戶端,服務(wù)器就需要使用"Transfer-Encoding: chunked"這樣的方式來代替Content-Length。 chunk編碼將數(shù)據(jù)分成一塊一塊的發(fā)生。Chunked編碼將使用若干個(gè)Chunk串連而成,由一個(gè)標(biāo)明長度為0 的chunk標(biāo)示結(jié)束。每個(gè)Chunk分為頭部和正文兩部分,頭部內(nèi)容指定正文的字符總數(shù)(十六進(jìn)制的數(shù)字 )和數(shù)量單位(一般不寫),正文部分就是指定長度的實(shí)際內(nèi)容,兩部分之間用回車換行(CRLF) 隔開。在最后一個(gè)長度為0的Chunk中的內(nèi)容是稱為footer的內(nèi)容,是一些附加的Header信息(通常可以直接忽略)。 Chunk編碼的格式如下: Chunked-Body = *chunk? "0" CRLF? footer? CRLF ? chunk = chunk-size [ chunk-ext ] CRLF? chunk-data CRLF hex-no-zero = <HEX excluding "0"> chunk-size = hex-no-zero *HEX? chunk-ext = *( ";" chunk-ext-name [ "=" chunk-ext-value ] )? chunk-ext-name = token? chunk-ext-val = token | quoted-string? chunk-data = chunk-size(OCTET) footer = *entity-header 即Chunk編碼由四部分組成: 1、0至多個(gè)chunk塊 ,2、"0" CRLF ,3、footer ,4、CRLF . 而每個(gè)chunk塊由:chunk-size、chunk-ext(可選)、CRLF、chunk-data、CRLF組成。 4、消息長度的總結(jié) 其實(shí),上面2中方法都可以歸納為是如何判斷http消息的大小、消息的數(shù)量。RFC 2616 對 消息的長度總結(jié)如下:一個(gè)消息的transfer-length(傳輸長度)是指消息中的message-body(消息體)的長度。當(dāng)應(yīng)用了 transfer-coding(傳輸編碼),每個(gè)消息中的message-body(消息體)的長度(transfer-length)由以下幾種情況 決定(優(yōu)先級由高到低): 任何不含有消息體的消息(如1XXX、204、304等響應(yīng)消息和任何頭(HEAD,首部)請求的響應(yīng)消息),總是由一個(gè)空行(CLRF)結(jié)束。 如果出現(xiàn)了Transfer-Encoding頭字段 并且值為非“identity”,那么transfer-length由“chunked” 傳輸編碼定義,除非消息由于關(guān)閉連接而終止。 如果出現(xiàn)了Content-Length頭字段,它的值表示entity-length(實(shí)體長度)和transfer-length(傳輸長 度)。如果這兩個(gè)長度的大小不一樣(i.e.設(shè)置了Transfer-Encoding頭字段),那么將不能發(fā)送Content-Length頭字段。并 且如果同時(shí)收到了Transfer-Encoding字段和Content-Length頭字段,那么必須忽略Content-Length字段。 如果消息使用媒體類型“multipart/byteranges”,并且transfer-length 沒有另外指定,那么這種自定界(self-delimiting)媒體類型定義transfer-length 。除非發(fā)送者知道接收者能夠解析該類型,否則不能使用該類型。 由服務(wù)器關(guān)閉連接確定消息長度。(注意:關(guān)閉連接不能用于確定請求消息的結(jié)束,因?yàn)榉?wù)器不能再發(fā)響應(yīng)消息給客戶端了。) 為了兼容HTTP/1.0應(yīng)用程序,HTTP/1.1的請求消息體中必須包含一個(gè)合法的Content-Length頭字段,除非知道服務(wù)器兼容 HTTP/1.1。一個(gè)請求包含消息體,并且Content-Length字段沒有給定,如果不能判斷消息的長度,服務(wù)器應(yīng)該用用400 (bad request) 來響應(yīng);或者服務(wù)器堅(jiān)持希望收到一個(gè)合法的Content-Length字段,用 411 (length required)來響應(yīng)。 所有HTTP/1.1的接收者應(yīng)用程序必須接受“chunked” transfer-coding (傳輸編碼),因此當(dāng)不能事先知道消息的長度,允許使用這種機(jī)制來傳輸消息。消息不應(yīng)該夠同時(shí)包含 Content-Length頭字段和non-identity transfer-coding。如果一個(gè)消息同時(shí)包含non-identity transfer-coding和Content-Length ,必須忽略Content-Length 。總結(jié)
以上是生活随笔為你收集整理的Keep-Alive模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux--select
- 下一篇: struc,union,class的内存