http 傳輸原理及格式

HTTP是Web協議集中的重要協議,它是從客戶機/服務器模型發展起來的。客戶機/服務器是運行一對相互通信的程序,客戶與服務器連接時,首先,向服務器提出請求,服務器根據客戶的請求,完成處理並給出響應。瀏覽器就是與Web服務器產生連接的客戶端程序,它的端口爲TCP的80端口。舉一個大家都很常見的例子,瀏覽器與Web服務器之間所遵循的協議就是HTTP。

Web的應用層協議HTTP是Web的核心。HTTP在Web的客戶程序和服務器程序中得以實現。運行在不同端系統上的客戶程序和服務器程序通過交換HTTP消息彼此交流。HTTP定義這些消息的結構以及客戶和服務器如何交換這些消息。HTTP定義Web客戶(即瀏覽器)如何從web服務器請求Web頁面,以及服務器如何把Web頁面傳送給客戶。

HTTP協議的優點就是可以解決傳輸數據的準確性、安全性較高、而且有處理網絡擁塞的能力。這主要的原因就是HTTP協議傳輸數據的時候,是由HTTP都把TCP作爲底層的傳輸協議。HTTP客戶首先發起建立與服務器TCP連接。一旦建立連接,瀏覽器進程和服務器進程就可以通過各自的套接字來訪問TCP。如前所述,客戶端套接字是客戶進程和TCP連接之間的“門”,服務器端套接字是服務器進程和同一TCP連接之間的門。客戶往自己的套接字發送HTTP請求消息,也從自己的套接字接收HTTP響應消息。類似的,服務器從自己的套接字接收HTTP請求消息,也往自己的套接字發送HTTP響應消息。客戶或服務器一旦把某個消息送入各自的套接字,這個消息就完全落入TCP的控制之中。

TCP給HTTP提供一個可靠的數據傳輸服務;這意味着由客戶發出的每個HTTP請求消息最終將無損地到達服務器,由服務器發出的每個HTTP響應消息最終也將無損地到達客戶。我們可從中看到分層網絡體系結構的一個明顯優勢——HTTP不必擔心數據會丟失,也無需關心TCP如何從數據的丟失和錯序中恢復出來的細節。HTTP/1.1服務器端處理請求時按照收到的順序進行,這就保證了傳輸的正確性。當然,服務器端在發生連接中斷時,會自動的重傳請求,保證數據的完整性。

值得注意的是HTTP協議的建立連接方式也非常特別,在早先的HTTP/1.0版本中使用的是非持久連接,而到了HTTP/1.1時非持久連接和持久連接都被支持,但默認使用持久連接。在此要說明非持久連接大概的過程是,舉一個瀏覽網頁的例子。首先客戶由與TCP連接相關聯的本地套接字發出—個HTTP請求消息;其次,服務器接受請求並且經由同一個套接字發送響應消息;然後HTTP服務器告知TCP關閉這個TCP連接(不過TCP要到客戶收到剛纔這個響應消息之後纔會真正終止這個連接);這時HTTP客戶經由同一個套接字接收這個響應消息後,TCP連接隨後終止。該消息明確標明所封裝的對象是一個什麼樣的文件。客戶從中取出這個文件,加以分析後發現其中的真正內容的引用。然後再對這些內容申請連接,最後瀏覽器就可以顯示出網頁的內容了,假如網頁的內容是由5幅圖片組成的那麼完成對網頁的瀏覽就需要有6次TCP的連接,這是HTTP/1.0版本的做法。

在HTTP/1.1中,在持久連接情況下,服務器在發出響應後讓TCP連接繼續打開着。同一對客戶/服務器之間的後續請求和響應可以通過這個連接發送。整個Web頁面(上例中爲包含一個基本HTML文件和5個圖像的頁面)可以通過單個持久TCP連接發送,甚至存放在同一個服務器中的多個web頁面也可以通過單個持久TCP連接發送。通常,HTTP服務器在某個連接閒置一段特定時間後關閉它,而這段時間通常是可以配置的。持久連接分爲不帶流水線(without pipelining)和帶流水線(with pipelining)兩個版本。如果是不帶流水線的版本,那麼客戶只在收到前一個請求的響應後才發出新的請求。這種情況下,web頁面所引用的每個對象(上例中的5個圖像)都經歷1個RTT的延遲,用於請求和接收該對象。與非持久連接2個RTT的延遲相比,不帶流水線的持久連接已有所改善,不過帶流水線的持久連接還能進一步降低響應延遲。不帶流水線版本的另一個缺點是,服務器送出一個對象後開始等待下一個請求,而這個新請求卻不能馬上到達。這段時間服務器資源便閒置了。HTTP/1.1的默認模式使用帶流水線的持久連接。這種情況下,HTTP客戶每碰到一個引用就立即發出一個請求,因而HTTP客戶可以一個接一個緊挨着發出各個引用對象的請求。服務器收到這些請求後,也可以一個接一個緊挨着發出各個對象。如果所有的請求和響應都是緊挨着發送的,那麼所有引用到的對象一共只經歷1個RTT的延遲(而不是像不帶流水線的版本那樣,每個引用到的對象都各有1個RTT的延遲)。另外,帶流水線的持久連接中服務器空等請求的時間比較少。與非持久連接相比,持久連接(不論是否帶流水線)除降低了1個RTT的響應延遲外,緩啓動延遲也比較小。其原因在於既然各個對象使用同一個TCP連接,服務器發出第一個對象後就不必再以一開始的緩慢速率發送後續對象。相反,服務器可以按照第一個對象發送完畢時的速率開始發送下一個對象。

從上面的例子不難看出,非持久連接中用戶的點擊導致瀏覽器發起建立一個與Web服務器的TCP連接,這裏涉及一個三次握手的過程:首先是客戶向服務器發送一個小的冗餘消息,接着是服務器向客戶確認並響應一個小的TCP消息,最後是客戶向服務器回確認。三次握手過程的前兩次結束時,流逝的時間爲1個RTT。此時客戶把HTTP請求消息發送到TCP連接中,客戶接着把三次握手過程最後一次中的確認捎帶,在包含這個消息的數據分節中發送出去。服務器收到來自TCP連接的請求消息後,把相應的HTML文件發送到TCP連接中,服務器接着把對早先收到的客戶請求的確認捎帶在包含該HTML文件的數據分節中發送出去。這個HTTP請求順應交互也花去1個RTT時間。很容易就能看出持久連接在時間損耗上的優勢了。

另外一個非常重要的地方就是HTTP協議的請求頭以及響應頭的格式。如果不清楚請求頭的格式就無法向服務器端準確地發送下載請求;同時響應頭的獲得信息,對下載工具下一步的處理也至關重要。下面列出HTTP請求消息:

GET/somedir/page.htmlHTTP/1.1

Host:www.hhit.edu.cn

Connection:close

User-agent:Mozilla/4.0

Accept-language:zh-cn

(額外的回車符和換行符)

首先,這個消息是用普通的ASCII文本書寫的。其次,這個消息共有5行(每行以一個回車符和一個換行符結束),最後一行後面還有額外的一個回車和換行符。當然,一個請求消息可以不止這麼多行,也可以僅僅只有一行。該請求消息的第一行稱爲請求行(request line),後續各行都稱爲頭部行(header)。請求行有3個字段:方法字段、URL字段、HTTP版本字段。方法字段有若干個值可供選擇,包括GET、POST和HEAD。HTTP請求消息絕大多數使用GET方法,這是瀏覽器用來請求對象的方法,所請求的對象就在URL字段中標識。本例中瀏覽器實現的是HTTP/1.1版本。

上面例子中的請求消息有四行他們的意思分別是:

頭部行Host:www.hhit.edu.cn存放所請求對象的主機。

請求消息中包含頭部Connection:close是在告知服務器本瀏覽器不想使用持久連接;服務器發出所請求的對象後應關閉連接。儘管產生這個請求消息的瀏覽器實現的是HTTP/1.1版本,它還是不想使用持久連接。

User-agent頭部行指定用戶代理,也就是產生當前請求的瀏覽器的類型。本例的用戶代理是Mozilla/4.0,它是Nelscape瀏覽器的一個版本。這個頭部行很有用,因爲服務器實際上可以給不同類型的用戶代理髮送同一個對象的不同版本(這些不同版本位用同一個URL尋址)。

最後,Accept-languag:頭部行指出要是所請求對象有簡體中文版本,那麼用戶寧願接收這個版本;如果沒有這個語言版本,那麼服務器應該發送其默認版本。Accept-languag:僅僅是HTTP的衆多內容協商頭部之一。

HTTP協議請求消息的一般格式如圖:

圖  HTTP協議的請求信息格式

值得注意的是在請求消息的最後是附屬體,在我們給出的例子中並沒有這一項。是因爲,附屬體不在GET方法中使用,而是在POST方法中使用。POST方法適用於需由用戶填寫表單的場合,如往google搜索引擎中填入待搜索的詞。用戶提交表單後,瀏覽器就像用戶點擊了超鏈接那樣仍然從服務器請求一個Web頁面,不過該頁面的具體內容卻取決於用戶填寫在表單各個字段中的值。如果瀏覽器使用POST方法提出該請求,那麼請求消息附屬體中包含的是用戶填寫在表單各個字段中的值。

HTTP協議的響應消息和請求消息有所不同,下面是一個典型的響應消息:

HTTP/1.1 200 OK

Connection:close

Date:Thu,13Oct200503:17:33GMT

Server:Apache/2.0.54(Unix)

Last-Modified:Mon,22Jun199809;23;24GMT

Content-Length:682l

Content-Type:text/html

(數據數據數據數據數據…………)

這個響應消息分爲3部分:1個起始的狀態行(Status Line),6個頭部行、1個包含所請求對象本身的附屬體。狀態行有3個字段:協議版本字段、狀態碼字段、原因短語字段。本例的狀態行表明,服務器使用HTTP/1.1版本,狀態碼(Status Codes)200表示響應過程完全正常(也就是說服務器找到了所請求的對象,並正在發送)。

在上面的響應消息中頭部行的意思分別是:

服務器使用Connection:close頭部行告知客戶自己將在發送完本消息後關閉TCP連接。

Date頭部行:指出服務器創建併發送本響應消息的日期和時間。注意,這並不是對象本身的創建時間或最後修改時間,而是服務器把該對象從其文件系統中取出,插入響應消息中發送出去的時間。

Server頭部行:指出本消息是由Apache服務器產生的;它與HTTP請求消息中的User-agent頭部行類似。

Last-Modified頭部行:指出對象本身的創建或最後修改日期或時間。Last-Modified頭部對於對象的高速緩存至關重要,且不論這種高速緩存是發生在本地客戶主機上還是發生在網絡高速緩存服務器主機(也就是代理服務器主機)上。

Content-Length頭部行:指出所發送對象的字節數。

Content-Type頭部行:指出包含在附屬體中的對象是HTML文本。對象的類型是由Content—Type頭部而不是由文件擴展名正式指出的。

HTTP響應消息格式如圖:

圖  HTTP協議的響應信息格式

圖 完整的HTTP請求響應內容

在響應消息中的狀態行明顯多出了明顯多出了狀態碼(Status Codes)和原因短語,是因爲在請求的信息可能存在着很多情況需要區分開,這樣也便於用戶能夠清楚地知道請求的情況以及出錯的原因,響應消息中的狀態碼和原因短語指示相應請求的處理結果。當服務器響應時,其狀態行的信息爲HTTP的版本號,狀態碼,及解釋狀態碼的簡單說明。現將5類狀態碼詳細列出:

1XX客戶方錯誤

100  繼續

101  交換協議

2XX成功

200  OK

201  已創建

202  接收

203  非認證信息

204  無內容

205  重置內容

206  部分內容

3XX重定向

300  多路選擇

301  永久轉移

302  暫時轉移

303  參見其它

304  未修改(Not Modified)

305  使用代理

4XX客戶方錯誤

400  錯誤請求(Bad Request)

401  未認證

402  需要付費

403  禁止(Forbidden)

404  未找到(Not Found)

405  方法不允許

406  不接受

407  需要代理認證

408  請求超時

409  衝突

410  失敗

411  需要長度

412  條件失敗

413  請求實體太大

414  請求URL太長

415  不支持媒體類型

5XX服務器錯誤

500  服務器內部錯誤

501  未實現(Not Implemented)

502  網關失敗

504  網關超時

505  HTTP版本不支持

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