http頭需知

【自:http://blog.csdn.net/zfrong/article/details/6070608
1、什麼是Keep-Alive模式?
我們知道HTTP協議採用“請求-應答”模式,當使用普通模式,即非KeepAlive模式時,每個請求/應答客戶和服務器都要新建一個連接,完成 之後立即斷開連接(HTTP協議爲無連接的協議);當使用Keep-Alive模式(又稱持久連接、連接重用)時,Keep-Alive功能使客戶端到服 務器端的連接持續有效,當出現對服務器的後繼請求時,Keep-Alive功能避免了建立或者重新建立連接。
File:HTTP persistent connection.svg
http 1.0中默認是關閉的,需要在http頭加入”Connection: Keep-Alive”,才能啓用Keep-Alive;http 1.1中默認啓用Keep-Alive,如果加入”Connection: close “,才關閉。目前大部分瀏覽器都是用http1.1協議,也就是說默認都會發起Keep-Alive的連接請求了,所以是否能完成一個完整的Keep- Alive連接就看服務器設置情況。
2、啓用Keep-Alive的優點
從上面的分析來看,啓用Keep-Alive模式肯定更高效,性能更高。因爲避免了建立/釋放連接的開銷。下面是RFC 2616 上的總結:

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)還指出:單用戶客戶端與任何服務器或代理之間的連接數不應該超過2個。一個代理與其它服務器或代碼之間應該使用超過2 * N的活躍併發連接。這是爲了提高HTTP響應時間,避免擁塞(冗餘的連接並不能代碼執行性能的提升)。
3、如何判斷消息內容/長度的大小?
Keep-Alive模式,客戶端如何判斷請求所得到的響應數據已經接收完成(或者說如何知道服務器已經發生完了數據)?我們已經知道 了,Keep-Alive模式發送玩數據HTTP服務器不會自動斷開連接,所有不能再使用返回EOF(-1)來判斷(當然你一定要這樣使用也沒有辦法,可 以想象那效率是何等的低)!下面我介紹兩種來判斷方法。
3.1、使用消息首部字段Conent-Length
故名思意,Conent-Length表示實體內容長度,客戶端(服務器)可以根據這個值來判斷數據是否接收完成。但是如果消息中沒有Conent-Length,那該如何來判斷呢?又在什麼情況下會沒有Conent-Length呢?請繼續往下看……
3.2、使用消息首部字段Transfer-Encoding
當客戶端向服務器請求一個靜態頁面或者一張圖片時,服務器可以很清楚的知道內容大小,然後通過Content-length消息首部字段告訴客戶端 需要接收多少數據。但是如果是動態頁面等時,服務器是不可能預先知道內容大小,這時就可以使用Transfer-Encoding:chunk模式來傳輸 數據了。即如果要一邊產生數據,一邊發給客戶端,服務器就需要使用”Transfer-Encoding: chunked”這樣的方式來代替Content-Length。
chunk編碼將數據分成一塊一塊的發生。Chunked編碼將使用若干個Chunk串連而成,由一個標明長度爲0 的chunk標示結束。每個Chunk分爲頭部和正文兩部分,頭部內容指定正文的字符總數(十六進制的數字 )和數量單位(一般不寫),正文部分就是指定長度的實際內容,兩部分之間用回車換行(CRLF) 隔開。在最後一個長度爲0的Chunk中的內容是稱爲footer的內容,是一些附加的Header信息(通常可以直接忽略)。
Chunk編碼的格式如下:
Chunked-Body = *chunk
“0” CRLF
footer
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
hex-no-zero =
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至多個chunk塊 ,2、”0” CRLF ,3、footer ,4、CRLF . 而每個chunk塊由:chunk-size、chunk-ext(可選)、CRLF、chunk-data、CRLF組成。
4、消息長度的總結
其實,上面2中方法都可以歸納爲是如何判斷http消息的大小、消息的數量。RFC 2616 對 消息的長度總結如下:一個消息的transfer-length(傳輸長度)是指消息中的message-body(消息體)的長度。當應用了 transfer-coding(傳輸編碼),每個消息中的message-body(消息體)的長度(transfer-length)由以下幾種情況 決定(優先級由高到低):
任何不含有消息體的消息(如1XXX、204、304等響應消息和任何頭(HEAD,首部)請求的響應消息),總是由一個空行(CLRF)結束。
如果出現了Transfer-Encoding頭字段 並且值爲非“identity”,那麼transfer-length由“chunked” 傳輸編碼定義,除非消息由於關閉連接而終止。
如果出現了Content-Length頭字段,它的值表示entity-length(實體長度)和transfer-length(傳輸長 度)。如果這兩個長度的大小不一樣(i.e.設置了Transfer-Encoding頭字段),那麼將不能發送Content-Length頭字段。並 且如果同時收到了Transfer-Encoding字段和Content-Length頭字段,那麼必須忽略Content-Length字段。
如果消息使用媒體類型“multipart/byteranges”,並且transfer-length 沒有另外指定,那麼這種自定界(self-delimiting)媒體類型定義transfer-length 。除非發送者知道接收者能夠解析該類型,否則不能使用該類型。
由服務器關閉連接確定消息長度。(注意:關閉連接不能用於確定請求消息的結束,因爲服務器不能再發響應消息給客戶端了。)
爲了兼容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 。
5、HTTP頭字段總結
最後我總結下HTTP協議的頭部字段。
1、 Accept:告訴WEB服務器自己接受什麼介質類型,**;q=0、5
Accept-Language:zh-cn,zh;q=0、5
Accept-Encoding:gzip,deflate
Accept-Charset:gb2312,utf-8;q=0、7,*;q=0、7
Keep-Alive:300
Connection:keep-alive
Cookie:userId=C5bYpXrimdmsiQmsBPnE1Vn8ZQmdWSm3WRlEB3vRwTnRtW <– Cookie
If-Modified-Since:Sun, 01 Jun 2008 12:05:30 GMT
Cache-Control:max-age=0
HTTP 響應消息頭部實例:
Status:OK - 200 <– 響應狀態碼,表示 web 服務器處理的結果。
Date:Sun, 01 Jun 2008 12:35:47 GMT
Server:Apache/2、0、61 (Unix)
Last-Modified:Sun, 01 Jun 2008 12:35:30 GMT
Accept-Ranges:bytes
Content-Length:18616
Cache-Control:max-age=120
Expires:Sun, 01 Jun 2008 12:37:47 GMT
Content-Type:application/xml
Age:2
X-Cache:HIT from 236-41、D07071951、sina、com、cn <– 反向代理服務器使用的 HTTP 頭部
Via:1.0 236-41.D07071951.sina.com.cn:80 (squid/2.6.STABLE13)
Connection:close

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章