在講HTTP、TCP、UDP之前先來看下TCP/IP五層網絡架構
TCP/IP通信數據流:
TCP/IP
協議族中有一個重要的概念是分層,TCP/IP協議
按照層次分為以下四層。應用層、傳輸層、網絡層、數據鏈路層、物理層
。其中TCP、UDP
屬于傳輸層協議,而HTTP
是基于 TCP/IP
協議的應用層協議,它不涉及數據包傳輸,主要規定了客戶端和服務器之間的通信格式,默認使用80端口。
物理層:
規定通信設備的機械的、電氣的、功能的和過程的特性,用以建立、維護和拆除物理鏈路連接;在這一層,數據的單位稱為比特(bit)。屬于物理層定義的典型規范代表包括:EIA/TIA RS-232、EIA/TIA RS-449、V.35、RJ-45等。
數據鏈路層:
在物理層提供比特流服務的基礎上,建立相鄰結點之間的數據鏈路,通過差錯控制提供數據幀(Frame)在信道上無差錯的傳輸,并進行各電路上的動作系列。數據鏈路層在不可靠的物理介質上提供可靠的傳輸。該層的作用包括:物理地址尋址、數據的成幀、流量控制、數據的檢錯、重發等。在這一層,數據的單位稱為幀(frame)。數據鏈路層協議的代表包括:SDLC、HDLC、PPP、STP、幀中繼等。
網絡層
:
在 計算機網絡中進行通信的兩個計算機之間可能會經過很多個數據鏈路,也可能還要經過很多通信子網。網絡層的任務就是選擇合適的網間路由和交換結點, 確保數據及時傳送。網絡層將數據鏈路層提供的幀組成數據包,包中封裝有網絡層包頭,其中含有邏輯地址信息- -源站點和目的站點地址的網絡地址
傳輸層:
網絡層負責點到點的傳輸(這里的"點"指主機或路由器),而傳輸層負責端到端的傳輸(這里的"端"指源主機和目的主機),提供應用程序間的通信。其功能包括:格式化信息流、提供可靠傳輸。為實現后者,傳輸層協議規定接收端必須發回確認,并且假如分組丟失,必須重新發送。傳輸層協議主要是:傳輸控制協議TCP
和用戶數據報協議UDP
。在這一層,數據的單位稱為 段
應用層:
應用層為操作系統或網絡應用程序提供訪問網絡服務的接口,向用戶提供一組常用的應用程序,比如電子郵件、文件傳輸訪問、遠程登錄等應用層,協議的代表包括:Telnet、FTP、HTTP、SNMP等。
TCP/UDP
TCP
和UDP
協議屬于傳輸層協議。其中TCP
提供IP環境下的數據可靠傳輸,它提供的服務包括數據流傳送、可靠性、有效流控、全雙工操作和多路復用。通過面向連接、端到端和可靠的數據包發送。通俗說,它是事先為所發送的數據開辟出連接好的通道,然后再進行數據發送;而UDP
則不為IP提供可靠性、流控或差錯恢復功能。一般來說,TCP
對應的是可靠性要求高的應用,而UDP
對應的則是可靠性要求低、傳輸經濟的應用。
1、面向連接的 TCP:
“面向連接”就是在正式通信前必須要與對方建立起連接。比如你給別人打電話,必須等線路接通了、對方拿起話筒才能相互通話。
TCP
是基于連接的協議,也就是說,在正式收發數據前,必須和對方建立可靠的連接。一個TCP
連接必須要經過三次“對話”才能建立起來,其中的過程非常復雜,我們這里只做簡單、形象的介紹如下圖:
TCP
使用窗口機制進行流量控制:連接建立時,各端分配一塊緩沖區用來存儲接收的數據,并將緩沖區的尺寸發送給另一端,接收方發送的確認信息中包含了自己剩余的緩沖區尺寸,剩余緩沖區空間的數量叫做窗口。TCP
的流控過程(滑動窗口):2、面向非連接的 UDP
“面向非連接”就是在正式通信前不必與對方先建立連接,不管對方狀態就直接發送。與手機短信非常相似:你在發短信的時候,只需要輸入對方手機號就OK了。
UDP
適用于一次只傳送少量數據、對可靠性要求不高的應用環境。比如,我們經常使用“ping”命令來測試兩臺主機之間TCP/IP
通信是否正常,其實“ping”命令的原理就是向對方主機發送ICMP數據包
,然后對方主機確認收到數據包,如果數據包是否到達的消息及時反饋回來,那么網絡就是通的。例如,在默認狀態下,一次“ping”操作發送4個數據包(如圖所示)。大家可以看到,發送的數據包數量是4包,收到的也是4包(因為對方主機收到后會發回一個確認收到的數據包)。這充分說明了UDP協議
是面向非連接的協議,沒有建立連接的過程。正因為UDP協議
沒有連接的過程,所以它的通信效率高;但也正因為如此,它的可靠性不如TCP協議
高。QQ就使用UDP
發消息,因此有時會出現收不到消息的情況。
TCP協議
和UDP協議
各有所長、各有所短,適用于不同要求的通信環境。TCP協議
和UDP協議
之間的差別如附表所示:
TCP使用場景:
對數據傳輸可靠性要求非常高,例如大家瀏覽網頁,通過網頁注冊帳號、轉帳等服務,這是不容許出錯的,使用TCP協議
能把出錯的可能性降到最低(當然,網絡自身很糟糕,TCP協議
也沒辦法)。但是,提供這種可靠服務,會加大網絡帶寬的開銷,因為“虛擬信道”是持續存在的,同時網絡中還會出現大量的ACK
和FIN
包!
UDP使用場景:
TCP協議
提供了可靠的數據傳輸,但是其擁塞控制、數據校驗、重傳機制的網絡開銷很大,不適合實時通信,所以選擇開銷很小的UDP協議
來傳輸數據。 UDP 協議
是無連接的數據傳輸協議并且無重傳機制,會發生丟包、收到重復包、亂序等情況。而對于數據精確性要求不高的狀態數據以及視頻數據,丟包的影響不大。因為會不斷收到新的包,丟失的個別包會有新的包來覆蓋,所以只需在遠程控制系統的通信部分自行處理亂序及重復包的問題,而對于丟包的問題一般不作處理。 但對于命令包這種需要精確收發的數據, 可在程序的開發中加入丟包重發和超時丟棄的處理。 當然,如果開發的是對于實時性要求不高的事件型控制命令的傳輸,不希望發生指令的丟失也可以直接采用TCP協議
。TCP
的重傳機制正好適合這種情況
HTTP
超文本傳輸協議
(HTTP
)是互聯網上應用最為廣泛的一種網絡協議。所有的WWW文件
都必須遵守這個標準。
通常,由HTTP
客戶端發起一個請求,建立一個到服務器指定端口(默認是80端口)的TCP
連接。HTTP
服務器則在那個端口監聽客戶端發送過來的請求。一旦收到請求,服務器(向客戶端)發回一個狀態行,比如"HTTP/1.1 200 OK"
,和(響應的)消息,消息的消息體可能是請求的文件、錯誤消息、或者其它一些信息。HTTP
使用TCP
而不是UDP
的原因在于(打開)一個網頁必須傳送很多數據,而TCP
協議提供傳輸控制,按順序組織數據,和錯誤糾正。
工作流程:
一次
HTTP
操作稱為一個事務,其工作過程可分為四步:1)首先客戶機與服務器需要建立連接。只要單擊某個超級鏈接,
HTTP
的工作開始。2)建立連接后,客戶機發送一個請求給服務器,請求方式的格式為:統一資源標識符(URL)、協議版本號,后邊是
MIME
信息包括請求修飾符、客戶機信息和可能的內容。3)服務器接到請求后,給予相應的響應信息,其格式為一個狀態行,包括信息的協議版本號、一個成功或錯誤的代碼,后邊是
MIME
信息包括服務器信息、實體信息和可能的內容。4)客戶端接收服務器所返回的信息通過瀏覽器顯示在用戶的顯示屏上,然后客戶機與服務器斷開連接。
如果在以上過程中的某一步出現錯誤,那么產生錯誤的信息將返回到客戶端,有顯示屏輸出。對于用戶來說,這些過程是由
HTTP
自己完成的,用戶只要用鼠標點擊,等待信息顯示就可以了。HTTP協議
永遠都是客戶端發起請求,服務器回送響應,這樣就限制了使用HTTP協議
,無法實現在客戶端沒有發起請求的時候,服務器將消息推送給客戶端。HTTP協議
是一個無狀態的協議,同一個客戶端的這次請求和上次請求是沒有對應關系。HTTP請求和回應
除了數據部分,每次通信都必須包括頭信息(HTTP header),用來描述一些元數據。其他的功能還包括狀態碼(status code)、多字符集支持、多部分發送(multi-part type)、權限(authorization)、緩存(cache)、內容編碼(content encoding)等
使用Wireshark抓TCP、http包:
在上圖中,可清晰的看到客戶端瀏覽器(ip為192.168.2.33)與服務器的交互過程:
1)No1:瀏覽器(192.168.2.33)向服務器(220.181.50.118)發出連接請求。此為TCP三次握手第一步,此時從圖中可以看出,為SYN,seq:X (x=0) 2)No2:服務器(220.181.50.118)回應了瀏覽器(192.168.2.33)的請求,并要求確認,此時為:SYN,ACK,此時seq:y(y為0),ACK:x+1(為1),此為三次握手的第二步; 3)No3:瀏覽器(192.168.2.33)回應了服務器(220.181.50.118)的確認,連接成功。為:ACK,此時seq:x+1(為1),ACK:y+1(為1)。此為三次握手的第三步; 4)No4:瀏覽器(192.168.2.33)發出一個頁面HTTP請求; 5)No5:服務器(220.181.50.118)確認; 6)No6:服務器(220.181.50.118)發送數據; 7)No7:客戶端瀏覽器(192.168.2.33)確認; 8)No14:客戶端(192.168.2.33)發出一個圖片HTTP請求; 9)No15:服務器(220.181.50.118)發送狀態響應碼200 OK ……
請求格式(Charles抓包工具):
以請求網址http://image.baidu.com/為例
請求:
響應:
第一行是請求命令,必須在尾部添加協議版本
HTTP/1.1
。后面就是多行頭信息,描述客戶端的情況。
回應格式
服務器的回應如下:
回應的格式是頭信息 + 一個空行(\r\n) + 數據
。其中,第一行是協議版本 + 狀態碼(status code) + 狀態描述
。
host頭域:
Host頭域
指定請求資源的Intenet主機和端口號,必須表示請求url的原始服務器或網關的位置。HTTP/1.1
請求必須包含主機頭域,否則系統會以400
狀態碼返回。
圖中host那行為:
Host image.baidu.com
Referer頭域
Referer頭域允許客戶端指定請求uri的源資源地址,這可以允許服務器生成回退鏈表,可用來登陸、優化cache等。他也允許廢除的或錯誤的連接由于維護的目的被追蹤。如果請求的uri沒有自己的uri地址,Referer不能被發送。如果指定的是部分uri地址,則此地址應該是一個相對地址。
在圖中,Referer行的內容為:
Referer http://image.baidu.com
User-Agent頭域
User-Agent
頭域的內容包含發出請求的用戶信息。
在圖中,User-Agent行的內容為:
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/602.2.14 (KHTML, like Gecko) Version/10.0.1 Safari/602.2.14
Cache-Control頭域
Cache-Control
指定請求和響應遵循的緩存機制。在請求消息或響應消息中設置Cache-Control
并不會修改另一個消息處理過程中的緩存處理過程。請求時的緩存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached
,響應消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age
。
Date頭域
Date頭域
表示消息發送的時間,時間的描述格式由rfc822
定義。例如,Date:Mon,31Dec200104:25:57GMT
。Date
描述的時間表示世界標準時,換算成本地時間,需要知道用戶所在的時區。
圖中,該頭域如下圖所示:
Date Thu, 01 Dec 2016 08:07:52 GMT
Content-Type字段:
關于字符的編碼,1.0版規定,頭信息必須是 ASCII 碼,后面的數據可以是任何格式。因此,服務器回應的時候,必須告訴客戶端,數據是什么格式,這就是Content-Type
字段的作用。
下面是一些常見的Content-Type
字段的值:
text/plain
text/html
text/css
image/jpeg
image/png
image/svg+xml
audio/mp4
video/mp4
application/javascript
application/pdf
application/zip
application/atom+xml
這些數據類型總稱為MIME type
,每個值包括一級類型和二級類型,之間用/
分隔。除了預定義的類型,廠商也可以自定義類型。
application/vnd.debian.binary-package
上面的類型表明,發送的是Debian系統的二進制數據包。
MIME type
還可以在尾部使用分號,添加參數:
Content-Type: text/html; charset=utf-8
上面的類型表明,發送的是網頁,而且編碼是UTF-8
。
客戶端請求的時候,可以使用Accept
字段聲明自己可以接受哪些數據格式。
Accept: */*
上面代碼中,客戶端聲明自己可以接受任何格式的數據。
MIME type
不僅用在HTTP協議
,還可以用在其他地方,比如HTML
網頁。
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<!-- 等同于 -->
<meta charset="utf-8" />
Content-Encodeing字段
由于發送的數據可以是任何格式,因此可以把數據壓縮后再發送。Content-Encoding
字段說明數據的壓縮方法:
Content-Encoding: gzip
Content-Encoding: compress
Content-Encoding: deflate```
客戶端在請求時,用`Accept-Encoding`字段說明自己可以接受哪些壓縮方法:
`Accept-Encoding: gzip, deflate`
#### http 1.1中新的功能:
#####持久連接:
1.1 版的最大變化,就是引入了持久連接,即`TCP`連接默認不關閉,可以被多個請求復用,不用聲明`Connection: keep-alive`。
`HTTP/1.0` 每次請求都需要建立新的`TCP`連接,連接不能復用。`HTTP/1.1 `新的請求可以在上次請求建立的`TCP`連接之上發送,連接可以復用。優點是減少重復進行`TCP`三次握手的開銷,提高效率。
客戶端和服務器發現對方一段時間沒有活動,就可以主動關閉連接。不過,規范的做法是,客戶端在最后一個請求時,發送`Connection: close`,明確要求服務器`關閉TCP連接`。
在`http1.1`,`request`和`reponse`頭中都有可能出現一個`connection`的頭,此`header`的含義是當`client`和`server`通信時對于長鏈接如何進行處理。
`clien`t和`server`都是默認對方支持長鏈接的, 如果`client`使用`http1.1協議`,但又不希望使用長鏈接,則需要在`header`中指明`connection`的值為`close`;如果`server`方也不想支持長鏈接,則在`response`中也需要明確說明`connection`的值為`close`。不論`request`還是`response`的`header`中包含了值為`close`的`connection`,都表明當前正在使用的`TCP`鏈接在當天請求處理完畢后會被斷掉。以后`client`再進行新的請求時就必須創建新的`TCP`鏈接了。
注意:在同一個`TCP`連接中,新的請求需要等上次請求收到響應后,才能發送。
測試如下
終端輸入:
telnet www.baidu.com 80```
結果如下:
Trying 115.239.210.27...
Connected to www.a.shifen.com.
Escape character is '^]'.```
接著開始發請求消息,例如發送如下請求消息請求baidu的首頁消息,使用的`HTTP`協議為`HTTP/1.1`:
GET /index.html HTTP/1.1```
注意:copy如上的消息到終端后需要按兩個回車換行才能得到響應的消息,第一個回車換行是在命令后鍵入回車換行,是HTTP
協議要求的。第二個是確認輸入,發送請求。
最終結果:
 可看到,當采用
HTTP/1.1`時,連接不是在請求結束后就斷開的。等待幾秒鐘之后斷開,輸出:
Connection closed by foreign host.
若采用HTTP1.0
,在命令窗口鍵入:
GET /index.html HTTP/1.0```
此時可以看到請求結束之后馬上斷開
讀者還可以嘗試在使用`GET`或`POST`等時,帶上頭域信息,例如鍵入如下信息:
GET /index.html HTTP/1.1
connection: close
Host: www.baidu.com```
http的狀態響應碼
http的狀態響應碼
請求收到,繼續處理:
100——客戶必須繼續發出請求
101——客戶要求服務器根據請求轉換HTTP協議版本
操作成功收到,分析、接受:
200——交易成功
201——提示知道新文件的URL
202——接受和處理、但處理未完成
203——返回信息不確定或不完整
204——請求收到,但返回信息為空
205——服務器完成了請求,用戶代理必須復位當前已經瀏覽過的文件
206——服務器已經完成了部分用戶的GET請求
完成此請求必須進一步處理:
300——請求的資源可在多處得到
301——刪除請求數據
302——在其他地址發現了請求數據
303——建議客戶訪問其他URL或訪問方式
304——客戶端已經執行了GET,但文件未變化
305——請求的資源必須從服務器指定的地址得到
306——前一版本HTTP中使用的代碼,現行版本中不再使用
307——申明請求的資源臨時性刪除
請求包含一個錯誤語法或不能完成:
400-錯誤請求,如語法錯誤
401——未授權
HTTP 401.1 - 未授權:登錄失敗
HTTP 401.2 - 未授權:服務器配置問題導致登錄失敗
HTTP 401.3 - ACL 禁止訪問資源
HTTP 401.4 - 未授權:授權被篩選器拒絕
HTTP 401.5 - 未授權:ISAPI 或 CGI 授權失敗
402——保留有效ChargeTo頭響應
403——禁止訪問
HTTP 403.1 禁止訪問:禁止可執行訪問
HTTP 403.2 - 禁止訪問:禁止讀訪問
HTTP 403.3 - 禁止訪問:禁止寫訪問
HTTP 403.4 - 禁止訪問:要求 SSL
HTTP 403.5 - 禁止訪問:要求 SSL 128
HTTP 403.6 - 禁止訪問:IP 地址被拒絕
HTTP 403.7 - 禁止訪問:要求客戶證書
HTTP 403.8 - 禁止訪問:禁止站點訪問
HTTP 403.9 - 禁止訪問:連接的用戶過多
HTTP 403.10 - 禁止訪問:配置無效
HTTP 403.11 - 禁止訪問:密碼更改
HTTP 403.12 - 禁止訪問:映射器拒絕訪問
HTTP 403.13 - 禁止訪問:客戶證書已被吊銷
HTTP 403.15 - 禁止訪問:客戶訪問許可過多
HTTP 403.16 - 禁止訪問:客戶證書不可信或者無效
HTTP 403.17 - 禁止訪問:客戶證書已經到期或者尚未生效
404——沒有發現文件、查詢或URl
405——用戶在Request-Line字段定義的方法不允許
406——根據用戶發送的Accept拖,請求資源不可訪問
407——類似401,用戶必須首先在代理服務器上得到授權
408——客戶端沒有在用戶指定的餓時間內完成請求
409——對當前資源狀態,請求不能完成
410——服務器上不再有此資源且無進一步的參考地址
411——服務器拒絕用戶定義的Content-Length屬性請求
412——一個或多個請求頭字段在當前請求中錯誤
413——請求的資源大于服務器允許的大小
414——請求的資源URL長于服務器允許的長度
415——請求資源不支持請求項目格式
416——請求中包含Range請求頭字段,在當前請求資源范圍內沒有range指示值,請求也不包含If-Range請求頭字段
417——服務器不滿足請求Expect頭字段指定的期望值,如果是代理服務器,可能是下一級服務器不能滿足請求長。
服務器執行一個完全有效請求失敗:
HTTP 500 - 內部服務器錯誤
HTTP 500.100 - 內部服務器錯誤 - ASP 錯誤
HTTP 500-11 服務器關閉
HTTP 500-12 應用程序重新啟動
HTTP 500-13 - 服務器太忙
HTTP 500-14 - 應用程序無效
HTTP 500-15 - 不允許請求 global.asa
Error 501 - 未實現
HTTP 502 - 網關錯誤