[轉】:HTTP請求流程(一)----流程簡介

http://www.cnblogs.com/stg609/archive/2008/07/06/1236966.html

 

HTTP請求流程(一)----流程簡介

      最近一直在研究如何讓asp.net實現上傳大文件的功能,因此都沒怎麼寫技術類的文章了。惋惜的是至今還沒研究出來,慚愧~~~。不過由於這樣,也瞭解了一下http消息請求的大體過程。我就先簡單介紹下,而後再來說如何利用Telnet來模擬Http請求。講得不對的地方還但願你們給我指出來。由於內容比較多,因此分紅兩部分來寫。
      一、流程簡介
      二、Telnet模擬HTTP請求


      這篇咱們就來作一個簡單介紹。
      先提個問題:當咱們在瀏覽器的地址欄中輸入"http://www.baidu.com/",而後按"回車",這以後發生了什麼事?這裏先不回答,你們接着往下看先。

      咱們來分析一下:

      ·HTTP請求流程

      首先,http屬於Tcp/Ip模型中的應用層協議,而兩個應用程序(咱們這裏指的就是瀏覽器與服務器)之間要進行互相通訊,首先得創建Tcp鏈接,而後瀏覽器才能向服務器發送請求信息,服務器在接受到請求信息後,返回相應的應答信息,瀏覽器接收到來自服務器的應答信息後,對這些數據進行解釋執行。

      在http 1.0的版本中,瀏覽器的每次請求(也就是對每個頁面的訪問)都要求創建一次單獨的鏈接,在處理完每一次的請求後,就自動釋放鏈接。(這點咱們應該都有感受,好比咱們訪問一個頁面,當該頁面在瀏覽器中顯示出來的時候,咱們能夠拔掉網線,此時該頁面上的信息並不會丟失。)而當咱們請求的網頁文件中有不少圖片、音樂、電影等信息時,服務器返回的信息中並不直接包含圖片數據,而只是保存該圖片的連接,當瀏覽器進行解釋的時候,遇到圖片的url時,才向服務器發出對圖片的請求信息。可見若是一個網頁中包含多個圖片數據時,將會頻繁的與服務器創建鏈接,與釋放鏈接,這無疑會形成資源的浪費。html

                                                                                        http 1.0 請求模式

      而http 1.1則能夠在一次鏈接中處理多個請求,而且多個請求能夠重疊進行,不須要等待一個請求結束後再發送下一個請求。web

創建鏈接的方式瀏覽器

HTTP支持2中創建鏈接的方式:非持久鏈接和持久鏈接(HTTP1.1默認的鏈接方式爲持久鏈接)。緩存

1)  非持久鏈接服務器

讓咱們查看一下非持久鏈接狀況下從服務器到客戶傳送一個Web頁面的步驟。假設該貝面由1個基本HTML文件和10個JPEG圖像構成,並且全部這些對象都存放在同一臺服務器主機中。再假設該基本HTML文件的URL爲:gpcuster.cnblogs.com/index.html。asp.net

下面是具體步騾:工具

1.HTTP客戶初始化一個與服務器主機gpcuster.cnblogs.com中的HTTP服務器的TCP鏈接。HTTP服務器使用默認端口號80監聽來自HTTP客戶的鏈接創建請求。2.HTTP客戶經由與TCP鏈接相關聯的本地套接字發出—個HTTP請求消息。這個消息中包含路徑名/somepath/index.html。3.HTTP服務器經由與TCP鏈接相關聯的本地套接字接收這個請求消息,再從服務器主機的內存或硬盤中取出對象/somepath/index.html,經由同一個套接字發出包含該對象的響應消息。post

4.HTTP服務器告知TCP關閉這個TCP鏈接(不過TCP要到客戶收到剛纔這個響應消息以後纔會真正終止這個鏈接)。網站

5.HTTP客戶經由同一個套接字接收這個響應消息。TCP鏈接隨後終止。該消息標明所封裝的對象是一個HTML文件。客戶從中取出這個文件,加以分析後發現其中有10個JPEG對象的引用。ui

6.給每個引用到的JPEG對象重複步騾1-4。

上述步驟之因此稱爲使用非持久鏈接,緣由是每次服務器發出一個對象後,相應的TCP鏈接就被關閉,也就是說每一個鏈接都沒有持續到可用於傳送其餘對象。每一個TCP鏈接只用於傳輸一個請求消息和一個響應消息。就上述例子而言,用戶每請求一次那個web頁面,就產生11個TCP鏈接。

2)   持久鏈接

非持久鏈接有些缺點。首先,客戶得爲每一個待請求的對象創建並維護一個新的鏈接。對於每一個這樣的鏈接,TCP得在客戶端和服務器端分配TCP緩衝區,並維持TCP變量。對於有可能同時爲來自數百個不一樣客戶的請求提供服務的web服務器來講,這會嚴重增長其負擔。其次,如前所述,每一個對象都有2個RTT的響應延長——一個RTT用於創建TCP鏈接,另—個RTT用於請求和接收對象。最後,每一個對象都遭受TCP緩啓動,由於每一個TCP鏈接都起始於緩啓動階段。不過並行TCP鏈接的使用可以部分減輕RTT延遲和緩啓動延遲的影響。

在持久鏈接狀況下,服務器在發出響應後讓TCP鏈接繼續打開着。同一對客戶/服務器之間的後續請求和響應能夠經過這個鏈接發送。整個Web頁面(上例中爲包含一個基本HTMLL文件和10個圖像的頁面)自不用說能夠經過單個持久TCP鏈接發送:甚至存放在同一個服務器中的多個web頁面也能夠經過單個持久TCP鏈接發送。一般,HTTP服務器在某個鏈接閒置一段特定時間後關閉它,而這段時間一般是能夠配置的。持久鏈接分爲不帶流水線(without pipelining)和帶流水線(with pipelining)兩個版本。若是是不帶流水線的版本,那麼客戶只在收到前一個請求的響應後才發出新的請求。這種狀況下,web頁面所引用的每一個對象(上例中的10個圖像)都經歷1個RTT的延遲,用於請求和接收該對象。與非持久鏈接2個RTT的延遲相比,不帶流水線的持久鏈接已有所改善,不過帶流水線的持久鏈接還能進一步下降響應延遲。不帶流水線版本的另外一個缺點是,服務器送出一個對象後開始等待下一個請求,而這個新請求卻不能立刻到達。這段時間服務器資源便閒置了。

HTTP/1.1的默認模式使用帶流水線的持久鏈接。這種狀況下,HTTP客戶每碰到一個引用就當即發出一個請求,於是HTTP客戶能夠一個接一個緊挨着發出各個引用對象的請求。服務器收到這些請求後,也能夠一個接一個緊挨着發出各個對象。若是全部的請求和響應都是緊挨着發送的,那麼全部引用到的對象一共只經歷1個RTT的延遲(而不是像不帶流水線的版本那樣,每一個引用到的對象都各有1個RTT的延遲)。另外,帶流水線的持久鏈接中服務器空等請求的時間比較少。與非持久鏈接相比,持久鏈接(不管是否帶流水線)除下降了1個RTT的響應延遲外,緩啓動延遲也比較小。其緣由在於既然各個對象使用同一個TCP鏈接,服務器發出第一個對象後就沒必要再以一開始的緩慢速率發送後續對象。相反,服務器能夠按照第一個對象發送完畢時的速率開始發送下一個對象。      ·

HTTP請求消息

      1次完整的http請求消息包括:一個請求行、若干消息頭以及實體內容,而消息頭和實體內容能夠沒有,消息頭和實體內容間有一個空行。
      咱們來看一個例子(爲了便於說明,我在每行前加了序號):
            1 Get /mattmarg/ HTTP/1.0
            2 User-Agent: Mozilla/2.0 (Macintosh; I; PPC)
            3 Accept: text/html; */*
            4 Cookie: name = value
            5 Referer: http://www.XXX.com/a.html
      其中,第1行就是請求行:請求方式爲Get(除了Get以外,還有Post、Put、Delete方式),請求的文件位於"根目錄/mattmarg/"下,固然也能夠直接給出須要的頁面(如:/mattmarg/index.asp,也能夠加上一些其它字段 如:/mattmarg/index.asp?id=1&uid=xxx。當咱們經過Get請求時,提交給服務器的請求行長度不能超過1K,而若是利用Post方式,則是把所提交的信息以實體內容形式發送給服務器,因此若是服務器沒有限制的話,原則上講能夠傳輸無限大的內容),HTTP/1.0 表示了http的版本爲1.0。其他幾行就是消息頭了,消息頭主要是用來向服務器傳達某種信息或指示。如告訴服務器本身的終端(User-Agent)是什麼(若是是瀏覽器則返回相應的瀏覽器型號),終端所能夠解釋的類型(Accept)是什麼,是從哪一個頁面提交的請求(Referer),以及瀏覽器所能解釋的語言(Accept-Language)等等。咱們這裏拿Accept-Language來舉個例子,你們都知道google在中國大陸顯示的是簡體中文,而在其它的國家則顯示對應的語言,這個是怎麼作到的呢?其實就是瀏覽器向服務器遞交的請求信息中包含了Accept-Language,而咱們的瀏覽器默認是zh-cn,而後服務器在接受到該信息時返回對應的頁面。
      咱們能夠經過如下方法來驗證一下:
      一、打開瀏覽器->工具->internet選項->常規選項卡
      二、選擇"語言",可見默認的語言是中文
      三、選擇"添加",選擇一種語言,而後調節一下優先順序

      四、肯定以後,咱們再訪問一下 http://www.google.com/,是否是發現原來的簡體中文全都成了繁體字了。

      · HTTP響應消息

      
Http響應消息的格式爲:一個狀態行、若干消息頭和實體內容,其中消息頭和實體內容能夠沒有,消息頭和實體內容間有一個空行。
      咱們依舊先來看一個例子:
            01 HTTP/1.1 200 OK
            02 Server: Microsoft-IIS/5.1
            03 X-Powered-By: ASP.NET
            04 Date: Sun, 06 Jul 2008 11:01:21 GMT
            05 Content-Type: text/html
            06 Accept-Ranges: bytes
            07 Last-Modified: Wed, 02 Jul 2008 01:01:26 GMT
            08 ETag: "0f71527dfdbc81:ade"
            09 Content-Length: 46
            10
            11 <html><head></head><body>adfasfa</body></html>
      其中,01行是狀態行,用於顯示服務器響應的狀態,HTTP/1.1顯示了對應的http協議版本,200爲狀態數字,OK爲狀態信息用於解釋狀態數字(這裏OK對應200,表示請求正常);02~09是消息頭部分,10爲空行,11爲實體內容(也就是服務器返回的網頁內容)。

      好了,相信你們應該已經對這個http請求的流程有了一個大概的瞭解了吧,那麼咱們反過來回答下最初留下的問題:當咱們在瀏覽器的地址欄中輸入 " http://www.baidu.com/ " ,而後按"回車",這以後發生了什麼事?

      首先,瀏覽器找到該網址所指向的IP,而後與其創建TCP鏈接,接着向百度服務器提出Get請求,當服務器接收到咱們的請求後,向咱們傳送應答信息--百度的頁面,而後斷開鏈接。

      [補充]以上文章中主要是描述HTTP請求的大體流程,至於HTTP以前所創建的一系列鏈接,只用了"瀏覽器找到該網址所指向的IP,而後與其創建TCP鏈接"這句話或相似的話來帶過。根據朋友們的回覆顯得這個說法不是很恰當。因此我在這裏再補充些東西。
       一、獲取IP。瀏覽器地址欄中輸入"http://www.xxx.edu.cn/"並提交以後,首先它會在DNS本地緩存表中查找,若是有則直接告訴IP地址。若是沒有則要求網關DNS進行查找,如此下去,當找到對應的ip後,則返回給瀏覽器。
       二、創建TCP鏈接。當獲取到IP以後,就開始與所請求的服務器創建TCP鏈接,你能夠在下圖中發現syn,ack,這些標識符就是用來同步用的。
       三、鏈接創建後,就向服務器發出http請求(你們能夠從圖中看出來)。若是是HTTP1.0的版本則,每一次請求結束後,就釋放TCP鏈接。

(上圖中,因爲是第一次訪問網站,沒法在本地找到對應IP)


(短期內,第二次訪問同一網站)


參考:
1.張孝祥老師的HTTP協議詳解
2.http://www.cnblogs.com/stg609/articles/1231832.html
 
相關文章
相關標籤/搜索