1. 程式人生 > >HTTP基礎及telnet簡單命令

HTTP基礎及telnet簡單命令

一、HTTP概況


 

  20世紀90年代初期,一個主要的新興應用即全球資訊網(World Wide Web)登上了舞臺。Web是一個引起公眾注意的因特網應用。Web的應用層協議是超文字傳輸協議(HTTP),它是Web的核心。HTTP由兩個程式實現:一個客戶程式和一個伺服器程式。客戶程式和伺服器程式執行在不同的端系統中,通過交換HTTP報文進行會話。HTTP會話定義了這些報文的結構以及客戶和伺服器進行報文交換的方式。

  Web頁面(也叫文件)是由物件組成的。一個物件只是一個檔案,諸如一個HTML檔案、一個JPEG圖形、一個Java小程式或一個視訊片段這樣的檔案,且他們可通過一個URL地址定址。多數Web頁面含有一個HTML基本檔案以及幾個引用物件。例如,如果一個Web頁面包含HTML基本檔案和5個JPEG圖形,那麼這個Web頁面6個物件:一個HTML基本檔案加5個圖形。HTML基本檔案通過物件的URL地址引用頁面中的其他物件。每個URL地址由兩部分組成:存放物件的伺服器主機名和物件的路徑名。Web瀏覽器實現了HTTP的客戶端,Web伺服器實現了HTTP的伺服器端,它用於儲存Web物件,每個物件由URL定址。

  HTTP定義了Web客戶向Web伺服器請求Web頁面的方式,以及伺服器向客戶傳送Web頁面的方式,其基本思想就是當用戶請求一個Web頁面(如點選一個超連結)時,瀏覽器向伺服器發出對該頁面中所包含物件的HTTP請求報文,伺服器接收到請求並用包含這些物件的HTTP響應報文進行響應。

  HTTP使用TCP作為它的支撐運輸協議(而不是在UDP上執行)。HTTP客戶首先發起一個與伺服器的TCP連線。一旦連線建立,該瀏覽器和伺服器程序就可以通過套接字介面訪問TCP。客戶向它的套接字介面傳送HTTP請求報文並從它的套接字介面接收HTTP響應報文。類似的,伺服器從它的套接字介面接收HTTP請求報文和向它的套接字介面傳送HTTP響應報文。一旦客戶向他的套接字介面傳送了一個請求報文,該報文就脫離了客戶控制並進入TCP的控制。TCP為HTTP提供可靠資料傳輸服務。這意味著,一個客戶程序發出的每個HTTP請求報文最終能完整地到達伺服器;類似的,伺服器程序發出的每個HTTP響應報文最終能完整地到達客戶。

  注意到下列現象很重要:伺服器向客戶傳送被請求的檔案,而不儲存任何關於該客戶的狀態資訊。假如某個特定的客戶在短短的幾秒鐘內兩次請求同一個物件,伺服器並不會因為剛剛為該客戶提供了該物件就不再做出反應,而是重新發送該物件,就像伺服器已經完全忘記不久之前所做過的事一樣。因為HTTP伺服器並不儲存關於客戶的任何資訊,所以我們說HTTP是一個無狀態協議。


 

二、非持續連線和持續連線


 

  在許多因特網應用程式中,客戶和伺服器在一個相當長的時間範圍內通訊,其中客戶發出一系列請求並且伺服器對每個請求進行響應。依據應用程式以及該應用程式的使用方式,這一系列請求可以以規則的間隔週期性的或者間斷性的一個接一個發出。當這種客戶-伺服器的互動是經TCP進行的,應用程式的研製者就要做一個重要決定,即每個請求/響應對是經一個單獨的TCP連線傳送,還是所有的請求及其相應經相同的TCP連線傳送呢?採用前一種方法,該應用程式被稱為使用非持續連線;採用後一種方法,該應用程式被稱為使用持續連線。如HTTP既能夠使用非持續連線,也能夠使用持續連線。儘管HTTP在預設方式下使用持續連線,HTTP客戶和伺服器也能配置成非持續連線。

1.採用非持續連線的HTTP

  我們看看在非持續連線情況下,從伺服器向客戶傳送一個Web頁面的步驟。假設該頁面含有一個HTML基本檔案和10個JPEG圖形,並且這11個物件位於同一臺伺服器上。該HTML檔案的URL為:http://www.someSchool.edu/someDepartment/home.index。我們看看發生了什麼情況:

  • HTTP客戶程序在埠號80發起一個到伺服器www.someSchool.edu的TCP連線,該埠號是HTTP的預設埠。在客戶和伺服器上分別有一個套接字與該連線相關聯。

  • HTTP客戶經它的套接字向該伺服器傳送一個HTTP請求報文。請求報文中包含了路徑名/someDepartment/home.index。

  • HTTP伺服器程序經它的套接字接收該請求報文,從其儲存器(RAM或磁碟)中檢索出物件http://www.someSchool.edu/someDepartment/home.index,在一個HTTP響應報文中封裝物件,並通過其套接字向客戶傳送響應報文。

  • HTTP伺服器程序通知TCP斷開該TCP連線。(但是直到TCP確認客戶已經完整的收到響應報文為止,它才會實際中斷連線。

  • HTTP客戶接收響應報文,TCP連線關閉。該報文指出封裝的物件是一個HTML檔案,客戶從響應報文中提取出該檔案,檢查該HTML檔案,得到對10個JPEG圖形的引用。

  • 對每個引用的JPEG圖形物件重複前4個步驟。

  上面的步驟舉例說明了非持續連線的使用,其中每個TCP連線在伺服器傳送一個物件後關閉,即該連線並不為其他的物件而持續下來。值得注意的是每個TCP來接只傳輸一個請求報文和響應報文。

     在上面描述的步驟中,我們有意沒有明確客戶獲得這10個JPEG圖形物件是使用10個序列的TCP連線,還是某些JPEG物件使用了一些並行的TCP連線。事實上,使用者能配置現代瀏覽器以控制並行度。在預設方式下,大部分瀏覽器開啟5~10個並行的TCP連線,而每條連線處理一個請求響應事務。如果使用者願意,最大並行連線數可以設定為1,這樣10條連線就會序列建立。

  我們來簡單估算一下從客戶請求HTML基本檔案起到該客戶收到整個檔案止所花費的時間。為此,我們給出往返時間(Round-Trip Time,RTT)的定義,該時間是指一個短分組從客戶到伺服器然後再返回客戶所花費的時間。RTT包括分組傳播時延、分組在中間路由器和交換機上的排隊時延以及分組處理時延。現在考慮當用戶點選超連結時會發生什麼現象。如圖2-7所示,這引起瀏覽器在它和Web伺服器之間發起一個TCP連線;這涉及一次“三次握手”過程。即客戶向伺服器傳送一個小TCP報文段,伺服器用一個小TCP報文段做出確認和響應,最後,客戶向伺服器返回確認。三次握手中前兩個部分所耗費的時間佔用了一個RTT。完成了三次握手的前兩個部分後,客戶結合三次握手的第三部分(確認)向該TCP連線傳送一個HTTP請求報文。一旦該請求報文到達伺服器,伺服器就在該TCP連線上傳送HTML檔案。該HTTP請求/響應用去了另一個RTT。因此,粗略地將,總的響應時間就是兩個RTT加上伺服器傳輸HTML檔案的時間。

2.採用持續連線的HTTP

  非持續連線有一些缺點。首先,必須為每一個請求的物件建立和維護一個全新的連線。對於每個這樣的連線,在客戶和伺服器中都要分配TCP的緩衝區和保持TCP變數,這給Web伺服器帶來了嚴重的負擔,因為一臺Web伺服器可能同時服務於數以百計不同的客戶的請求。第二,就像我們剛描述的那樣,每一個物件經受兩倍RTT的交付時延,即一個RTT用於建立TCP,另一個RTT用於請求和接收一個物件。

  在採用持續連線的情況下,伺服器在傳送響應後保持該TCP連線開啟。在相同的客戶與伺服器之間的後續請求和響應報文能夠通過相同的連線進行傳送。特別是,一個完整的Web頁面(上例中的HTML基本檔案加上10個圖形)可以用單個持續TCP連線進行傳送。更有甚者,位於同一臺伺服器的多個Web頁面在從該伺服器傳送給同一個客戶時,可以在單個持續TCP連線上進行。可以一個接一個地發出對物件的這些請求,而不必等待對未決請求(流水線)的回答。一般來說,如果一條連線經過一定的時間間隔(一個可配置的超時間隔)仍未被使用,HTTP伺服器就關閉該連線。HTTP的預設模式是使用帶流水線的持續連線。


三、HTTP報文格式

  HTTP報文有兩種:請求報文和響應報文。

1.HTTP請求報文

  下面提供了一個典型的HTTP請求報文:

GET /somedir/page.html HTTP/1.1

Host: www.someschool.edu

Connection: close

User-agent: Mozilla/5.0

Accept-language: fr

  通過仔細觀察這個簡單的請求報文,我們就能知道很多東西。首先,我們看到該報文是用普通的ASCII文字書寫的,我們看到該報文由5行組成,每行由一個回車和換行符結束。最後一行後再附加一個回車換行符。一個請求報文能夠具有更多的行或者至少為一行。請求行的方法欄位可以取幾種不同的值,包括GET、POST、HEAD、PUT和DELETE。當瀏覽器請求一個物件時,使用GET方法,在URL欄位帶有請求物件的標識,在本例中,該瀏覽器正在請求物件/somedir/page.html。其版本欄位是自解釋的;在本例中,瀏覽器實現的是HTTP/1.1版本。現在我們看看本例的首部行。首部行Host: www.someschool.edu指明瞭物件所在的主機。你也許認為該首部行是不必要的,因為在該主機中已經有一條TCP連線存在了,但是,該首部行提供的資訊是Web代理快取記憶體所要求的。通過包含Connection: close首部行,該瀏覽器告訴伺服器不希望麻煩地使用持續連線,它要求伺服器在傳送完被請求的物件後就關閉這條連線。User-agent: 首部行用來指明使用者代理,即向伺服器傳送請求的瀏覽器型別。這裡瀏覽器型別是Mozilla/5.0,即Firefox瀏覽器。這個首部行是有用的,因為伺服器可以有效地為不同型別的使用者代理實際傳送相同物件的不同版本。(每個版本都由相同的URL定址。)最後,Accept-language: 首部行表示使用者想得到該物件的法語版本。如果伺服器中沒有這樣的物件的話,伺服器應當傳送它的預設版本。

  接下來看看如圖2-8所示的一個請求報文的通用格式。你可能注意到了在首部行(和附加的回車和換行)後有一個“實體主體”。使用GET方法是實體主體為空,而使用POST方法時才使用該實體主體。當用戶提交表單時,HTTP客戶常常使用POST方法,例如當用戶向搜尋引擎提供搜尋關鍵詞時。使用POST報文時,使用者仍可以向伺服器請求一個Web頁面,但Web頁面的特定內容依賴於使用者在表單欄位中輸入的內容。如果方法欄位的值為POST時,則實體主體中包含的就是使用者在表單欄位中的輸入值。

  當然,如果不提“用表單生成的請求報文不是必須使用POST方法”這一點,那將是失職。HTML表單經常使用GET方法,並在(表單欄位中)所請求的URL中包括輸入的資料。例如,一個表單使用GET方法,它有兩個欄位,分別填寫的是“monkeys”和“bananas”,這樣,該URL結構為www.somesite.com/animalsearch? monkeys&bananas。

  HEAD方法類似GET方法。當伺服器收到使用HEAD方法的請求時,將會用一個HTTP報文進行響應,但是並不返回請求物件。應用程式開發者常用HEAD方法進行除錯跟蹤。PUT方法常與Web發行工具聯合使用,它允許使用者上傳物件到指定的Web伺服器上指定的路徑(目錄)。PUT也被那些需要向Web伺服器上傳物件的應用程式使用。DELETE方法允許使用者或者應用程式刪除Web伺服器上的物件。

2.HTTP響應報文

  下面我們提供了一條典型的HTTP響應報文。該響應報文可以是對剛剛討論的例子中請求報文的響應。

HTTP/1.1 200 OK

Connection: close

Date: Tue, 09 Aug 2011 15:44:04 GMT

Server: Apache/2.2.3 (CentOS)

Last-Modified: Tue, 09 Aug 2011 15:11:03 GMT

Content-Length: 6821

Content-Type: text/html

(data data data data data ...)

  我們仔細看這個響應報文。實體主體部分是報文的主要部分,即它包含了所請求的物件本身(表示為data data data data data ...)。我們現在來看看首部行。伺服器用Connection:close首部行告訴客戶,傳送完報文後將關閉該TCP連線。Date:首部行指示伺服器產生併發送該響應報文的日期和時間。值得一提的是,這個時間不是指物件建立或者最後修改的時間;而是伺服器從它的檔案系統中檢索到該物件,插入到響應報文,併發送響應報文的時間。Server:首部行指示該報文是由一臺Apache Web伺服器產生的,它類似於HTTP請求報文中的User-agent:首部行,Last-Modified:首部行指示了物件建立或者最後修改的日期和時間。Last-Modified:首部行對極可能在本地客戶也可能在網路快取伺服器(代理伺服器)上的物件快取來說非常重要。Content-Length:首部行知識了被髮送物件中的位元組數。Content-Type:首部行指示了實體主體中的物件是HTML文字。(該物件型別應該正式地由Content-Type:首部行而不是用副檔名來指示。)

  看過一個例子後,我們再來檢視響應報文的通用格式(如圖2-9所示)。我們補充說明一下狀態碼和它們對應的短語。狀態碼及其相應的短語指示了請求的結果。一些常見的狀態碼和相關的短語包括:

  • 200 OK:請求成功,資訊在返回的響應報文中。

  • 301 Moved Permanently:請求的物件已經被永久轉移了,新的URL定義在響應報文的Location:首部行中。**客戶軟體將自動獲取新的URL。

  • 400 Bad Request:一個通用差錯程式碼,指示該請求不能被伺服器理解。

  • 404 Not Found:被請求的文件不在伺服器上。

  • 505 HTTP Version Not Supported:伺服器不支援請求報文使用的HTTP協議版本。

  你想看一下真正的HTTP響應報文嗎?很容易做到。首先用Telnet登入到你喜歡的Web伺服器上,接下來輸入一個只有一行的請求報文去請求放在該伺服器上的某些物件。

  在linux終端輸入完telnet www.baidu.com 80後,會是下面這種情況:

  然後按下ctrl + ]撥出telnet命令列出現下面這種情況:

  先按下回車鍵,再輸入HTTP請求,最終得到HTTP響應如下:

  在telnet命令列上輸入quit退出telnet,如下圖:

 


 

&n