1. 程式人生 > >一次完整的HTTP請求與響應

一次完整的HTTP請求與響應

作者:Ruheng

本文以HTTP請求和響應的過程來講解涉及到的相關知識點。

第一

HTTP請求和相應步驟


圖片來自:理解Http請求與響應http://android.jobbole.com/85218/

以上完整表示了HTTP請求和響應的7個步驟,下面從TCP/IP協議模型的角度來理解HTTP請求和響應如何傳遞的。

第二

TCP/IP協議

TCP/IP協議模型(Transmission Control Protocol/Internet Protocol),包含了一系列構成網際網路基礎的網路協議,是Internet的核心協議,通過20多年的發展已日漸成熟,並被廣泛應用於區域網和廣域網中,目前已成為事實上的國際標準。TCP/IP協議簇是一組不同層次上的多個協議的組合,通常被認為是一個四層協議系統,與OSI的七層模型相對應。

HTTP協議就是基於TCP/IP協議模型來傳輸資訊的。


(1). 鏈路層

也稱作資料鏈路層或網路介面層(在第一個圖中為網路介面層和硬體層),通常包括作業系統中的裝置驅動程式和計算機中對應的網路介面卡。它們一起處理與電纜(或其他任何傳輸媒介)的物理介面細節。ARP(地址解析協議)和RARP(逆地址解析協議)是某些網路介面(如乙太網和令牌環網)使用的特殊協議,用來轉換IP層和網路介面層使用的地址。

(2). 網路層

也稱作網際網路層(在第一個圖中為網際層),處理分組在網路中的活動,例如分組的選路。在TCP/IP協議族中,網路層協議包括IP協議(網際協議),ICMP協議(Internet網際網路控制報文協議),以及IGMP協議(Internet組管理協議)。

IP是一種網路層協議,提供的是一種不可靠的服務,它只是儘可能快地把分組從源結點送到目的結點,但是並不提供任何可靠性保證。同時被TCP和UDP使用。TCP和UDP的每組資料都通過端系統和每個中間路由器中的IP層在網際網路中進行傳輸。

ICMP是IP協議的附屬協議。IP層用它來與其他主機或路由器交換錯誤報文和其他重要資訊。

IGMP是Internet組管理協議。它用來把一個UDP資料報多播到多個主機。

(3). 傳輸層

主要為兩臺主機上的應用程式提供端到端的通訊。在TCP/IP協議族中,有兩個互不相同的傳輸協議:TCP(傳輸控制協議)和UDP(使用者資料報協議)。

TCP為兩臺主機提供高可靠性的資料通訊。它所做的工作包括把應用程式交給它的資料分成合適的小塊交給下面的網路層,確認接收到的分組,設定傳送最後確認分組的超時時鐘等。由於運輸層提供了高可靠性的端到端的通訊,因此應用層可以忽略所有這些細節。為了提供可靠的服務,TCP採用了超時重傳、傳送和接收端到端的確認分組等機制。

UDP則為應用層提供一種非常簡單的服務。它只是把稱作資料報的分組從一臺主機發送到另一臺主機,但並不保證該資料報能到達另一端。一個數據報是指從傳送方傳輸到接收方的一個資訊單元(例如,傳送方指定的一定位元組數的資訊)。UDP協議任何必需的可靠性必須由應用層來提供。(4). 應用層

應用層決定了向用戶提供應用服務時通訊的活動。TCP/IP 協議族內預存了各類通用的應用服務。包括 HTTP,FTP(File Transfer Protocol,檔案傳輸協議),DNS(Domain Name System,域名系統)服務。


當應用程式用TCP傳送資料時,資料被送入協議棧中,然後逐個通過每一層直到被當作一串位元流送入網路。其中每一層對收到的資料都要增加一些首部資訊(有時還要增加尾部資訊),該過程如圖所示。


當目的主機收到一個乙太網資料幀時,資料就開始從協議棧中由底向上升,同時去掉各層協議加上的報文首部。每層協議盒都要去檢查報文首部中的協議標識,以確定接收資料的上層協議。這個過程稱作分用(Demultiplexing)。協議是通過目的埠號、源I P地址和源埠號進行解包的。

通過以上步驟我們從TCP/IP模型的角度來理解了一次HTTP請求與響應的過程。

下面這張圖更清楚明白:


下面具體來看如何進行一步步操作的。

第三

TCP三次握手

TCP是面向連線的,無論哪一方向另一方傳送資料之前,都必須先在雙方之間建立一條連線。在TCP/IP協議中,TCP協議提供可靠的連線服務,連線是通過三次握手進行初始化的。三次握手的目的是同步連線雙方的序列號和確認號並交換 TCP視窗大小資訊。


第一次握手:建立連線。客戶端傳送連線請求報文段,將SYN位置為1,Sequence Number為x;然後,客戶端進入SYN_SEND狀態,等待伺服器的確認;

第二次握手:伺服器收到SYN報文段。伺服器收到客戶端的SYN報文段,需要對這個SYN報文段進行確認,設定Acknowledgment Number為x+1(Sequence Number+1);同時,自己自己還要傳送SYN請求資訊,將SYN位置為1,Sequence Number為y;伺服器端將上述所有資訊放到一個報文段(即SYN+ACK報文段)中,一併傳送給客戶端,此時伺服器進入SYN_RECV狀態;

第三次握手:客戶端收到伺服器的SYN+ACK報文段。然後將Acknowledgment Number設定為y+1,向伺服器傳送ACK報文段,這個報文段傳送完畢以後,客戶端和伺服器端都進入ESTABLISHED狀態,完成TCP三次握手。

為什麼要三次握手

為了防止已失效的連線請求報文段突然又傳送到了服務端,因而產生錯誤。

具體例子:“已失效的連線請求報文段”的產生在這樣一種情況下:client發出的第一個連線請求報文段並沒有丟失,而是在某個網路結點長時間的滯留了,以致延誤到連線釋放以後的某個時間才到達server。本來這是一個早已失效的報文段。但server收到此失效的連線請求報文段後,就誤認為是client再次發出的一個新的連線請求。於是就向client發出確認報文段,同意建立連線。假設不採用“三次握手”,那麼只要server發出確認,新的連線就建立了。由於現在client並沒有發出建立連線的請求,因此不會理睬server的確認,也不會向server傳送資料。但server卻以為新的運輸連線已經建立,並一直等待client發來資料。這樣,server的很多資源就白白浪費掉了。採用“三次握手”的辦法可以防止上述現象發生。例如剛才那種情況,client不會向server的確認發出確認。server由於收不到確認,就知道client並沒有要求建立連線。”

第四

HTTP協議

Http是什麼?

通俗來講,他就是計算機通過網路進行通訊的規則,是一個基於請求與響應,無狀態的,應用層的協議,常基於TCP/IP協議傳輸資料。目前任何終端(手機,膝上型電腦。。)之間進行任何一種通訊都必須按照Http協議進行,否則無法連線。

四個基於:

請求與響應:客戶端傳送請求,伺服器端響應資料

無狀態的:協議對於事務處理沒有記憶能力,客戶端第一次與伺服器建立連線傳送請求時需要進行一系列的安全認證匹配等,因此增加頁面等待時間,當客戶端向伺服器端傳送請求,伺服器端響應完畢後,兩者斷開連線,也不儲存連線狀態,一刀兩斷!恩斷義絕!從此路人!下一次客戶端向同樣的伺服器傳送請求時,由於他們之前已經遺忘了彼此,所以需要重新建立連線。

應用層:Http是屬於應用層的協議,配合TCP/IP使用。

TCP/IP:Http使用TCP作為它的支撐運輸協議。HTTP客戶機發起一個與伺服器的TCP連線,一旦連線建立,瀏覽器(客戶機)和伺服器程序就可以通過套接字介面訪問TCP。

針對無狀態的一些解決策略:

有時需要對使用者之前的HTTP通訊狀態進行儲存,比如執行一次登陸操作,在30分鐘內所有的請求都不需要再次登陸。於是引入了Cookie技術。

HTTP/1.1想出了持久連線(HTTP keep-alive)方法。其特點是,只要任意一端沒有明確提出斷開連線,則保持TCP連線狀態,在請求首部欄位中的Connection: keep-alive即為表明使用了持久連線。等等還有很多。。。。。。

下面開始講解重頭戲:HTTP請求報文,響應報文,對應於上述步驟的2,3,4,5,6。

HTTP報文是面向文字的,報文中的每一個欄位都是一些ASCII碼串,各個欄位的長度是不確定的。HTTP有兩類報文:請求報文和響應報文。

第五

HTTP請求報文

一個HTTP請求報文由請求行(request line)、請求頭部(header)、空行和請求資料4個部分組成,下圖給出了請求報文的一般格式。


1.請求行

請求行分為三個部分:請求方法、請求地址和協議版本

請求方法

HTTP/1.1 定義的請求方法有8種:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、TRACE。

最常的兩種GET和POST,如果是RESTful介面的話一般會用到GET、POST、DELETE、PUT。

請求地址

URL:統一資源定位符,是一種自願位置的抽象唯一識別方法。

組成:<協議>://<主機>:<埠>/<路徑>

埠和路徑有時可以省略(HTTP預設埠號是80)

如下例:


有時會帶引數,GET請求

協議版本

協議版本的格式為:HTTP/主版本號.次版本號,常用的有HTTP/1.0和HTTP/1.1

2.請求頭部

請求頭部為請求報文添加了一些附加資訊,由“名/值”對組成,每行一對,名和值之間使用冒號分隔。

常見請求頭如下:


請求頭部的最後會有一個空行,表示請求頭部結束,接下來為請求資料,這一行非常重要,必不可少。

3.請求資料

可選部分,比如GET請求就沒有請求資料。

下面是一個POST方法的請求報文:

POST  /index.php HTTP/1.1    請求行Host: localhostUser-Agent: Mozilla/5.0 (Windows NT 5.1; rv:10.0.2) Gecko/20100101 Firefox/10.0.2  請求頭Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8Accept-Language: zh-cn,zh;q=0.5Accept-Encoding: gzip, deflateConnection: keep-aliveReferer: http://localhost/

Content-Length:25Content-Type:application/x-www-form-urlencoded  空行username=aa&password=1234  請求資料

第六

HTTP響應報文


HTTP響應報文主要由狀態行、響應頭部、空行以及響應資料組成。

1.狀態行

由3部分組成,分別為:協議版本,狀態碼,狀態碼描述。

其中協議版本與請求報文一致,狀態碼描述是對狀態碼的簡單描述,所以這裡就只介紹狀態碼。

狀態碼

狀態程式碼為3位數字。1xx:指示資訊--表示請求已接收,繼續處理。2xx:成功--表示請求已被成功接收、理解、接受。3xx:重定向--要完成請求必須進行更進一步的操作。4xx:客戶端錯誤--請求有語法錯誤或請求無法實現。5xx:伺服器端錯誤--伺服器未能實現合法的請求。

下面列舉幾個常見的:


2.響應頭部

與請求頭部類似,為響應報文添加了一些附加資訊

常見響應頭部如下:


3.響應資料

用於存放需要返回給客戶端的資料資訊。

下面是一個響應報文的例項:

HTTP/1.1 200 OK  狀態行Date: Sun, 17 Mar 2013 08:12:54 GMT  響應頭部Server: Apache/2.2.8 (Win32) PHP/5.2.5X-Powered-By: PHP/5.2.5Set-Cookie: PHPSESSID=c0huq7pdkmm5gg6osoe3mgjmm3; path=/Expires: Thu, 19 Nov 1981 08:52:00 GMTCache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0Pragma: no-cacheContent-Length: 4393Keep-Alive: timeout=5, max=100Connection: Keep-AliveContent-Type: text/html; charset=utf-8  空行

<html>  響應資料<head><title>HTTP響應示例<title></head><body>Hello HTTP!</body></html>

關於請求頭部和響應頭部的知識點很多,這裡只是簡單介紹。

通過以上步驟,資料已經傳遞完畢,HTTP/1.1會維持持久連線,但持續一段時間總會有關閉連線的時候,這時候據需要斷開TCP連線。

第七

TCP四次揮手

當客戶端和伺服器通過三次握手建立了TCP連線以後,當資料傳送完畢,肯定是要斷開TCP連線的啊。那對於TCP的斷開連線,這裡就有了神祕的“四次分手”。


第一次分手:主機1(可以使客戶端,也可以是伺服器端),設定Sequence Number,向主機2傳送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有資料要傳送給主機2了;

第二次分手:主機2收到了主機1傳送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number為Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我“同意”你的關閉請求;

第三次分手:主機2向主機1傳送FIN報文段,請求關閉連線,同時主機2進入LAST_ACK狀態;

第四次分手:主機1收到主機2傳送的FIN報文段,向主機2傳送ACK報文段,然後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段以後,就關閉連線;此時,主機1等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,主機1也可以關閉連線了。

為什麼要四次分手

TCP協議是一種面向連線的、可靠的、基於位元組流的運輸層通訊協議。TCP是全雙工模式,這就意味著,當主機1發出FIN報文段時,只是表示主機1已經沒有資料要傳送了,主機1告訴主機2,它的資料已經全部發送完畢了;但是,這個時候主機1還是可以接受來自主機2的資料;當主機2返回ACK報文段時,表示它已經知道主機1沒有資料傳送了,但是主機2還是可以傳送資料到主機1的;當主機2也傳送了FIN報文段時,這個時候就表示主機2也沒有資料要傳送了,就會告訴主機1,我也沒有資料要傳送了,之後彼此就會愉快的中斷這次TCP連線。

通過以上步驟便完成了HTTP的請求和響應,進行了資料傳遞,這其中涉及到需要知識點,都進行了逐一瞭解。

參考文章

你需要了解的HTTP知識都在這裡了!http://www.jianshu.com/p/a6d086a3997dHTTP知識點總結http://www.jianshu.com/p/2ecd288d27ad理解Http請求與響應http://android.jobbole.com/85218/HTTP-請求、響應、快取https://cnbin.github.io/blog/2016/02/20/http-qing-qiu-,-xiang-ying-,-huan-cun/你應該知道的HTTP基礎知識http://www.jianshu.com/p/e544b7a76dac整理Http知識點http://www.jellythink.com/archives/705簡析TCP的三次握手與四次分手http://www.jellythink.com/archives/705HTTP請求報文和HTTP響應報文http://www.cnblogs.com/biyeymyhjob/archive/2012/07/28/2612910.htmlTCP/IP協議簇分層詳解http://blog.csdn.net/hankscpp/article/details/8611229HTTP請求報文和HTTP響應報文http://www.cnblogs.com/biyeymyhjob/archive/2012/07/28/2612910.html

E