1. 程式人生 > >網絡協議詳解

網絡協議詳解

網絡協議 test 未能 第一個 為什麽 體系 index 緩存 hyper

目錄::::::

一、網絡協議

二、TCP(Transmission Control Protocol,傳輸控制協議)

TCP頭格式
TCP協議中的三次握手和四次揮手
TCP報文抓取工具
三、HTTP(HyperText Transfer Protocol,超文本傳輸協議)

請求報文結構
請求報文樣例
請求報文參數詳解
響應報文結構
響應報文樣例
響應報文參數詳解
HTTP報文抓取工具
Session和Cookie
四、相關資料

---------------------------------------------------------------------------------------------

一、網絡協議

國際標準化組織(International Standard Organization,ISO)公布了開放系統互連參考模型(OSI/RM)。OSI/RM是一種分層的體系結構,參考模型共有7層。
TCP/IP(Transmission Control Protocol/Internet Protocol)作為Internet的核心協議。它是個協議族,包含多種協議。
分層的基本想法是每一層都在它的下層提供的服務基礎上提供更高級的增值服務,而最高層提供能運行分布式應用程序的服務。
技術分享
發送請求的過程是從最頂層(應用層)出發,每一層負責封裝屬於自己的信息到請求中,最後將一整個請求發送給對方。
接收請求的過程是從最底層(網絡接口層)開始,每一層的協議負責解析屬於自己的東西,比如網際層(IP)處理ip信息,傳輸層(TCP)處理點對點的端口,應用層(HTTP)處理Request或Response的Line\Header\Body。

二、TCP(Transmission Control Protocol,傳輸控制協議)

TCP是一種面向連接(連接導向)的、可靠的基於字節流的傳輸層通信協議。TCP將用戶數據打包成報文段,它發送後啟動一個定時器,另一端收到的數據進行確認、對失序的數據重新排序、丟棄重復數據。
TCP的特點有:

  • TCP是面向連接的運輸層協議
  • 每一條TCP連接只能有兩個端點,每一條TCP連接只能是點對點的
  • TCP提供可靠交付的服務
  • TCP提供全雙工通信。數據在兩個方向上獨立的進行傳輸。因此,連接的每一端必須保持每個方向上的傳輸數據序號。
  • 面向字節流。面向字節流的含義:雖然應用程序和TCP交互是一次一個數據塊,但TCP把應用程序交下來的數據僅僅是一連串的無結構的字節流。

1、TCP頭格式

技術分享

(1) Source Port(源端口號):數據發起者的端口號,16bit。
(2) Destination Port(目的端口號):數據接收者的端口號,16bit。
(3) Sequence Number(順序號碼,Seq):用於在數據通信中解決網絡包亂序(reordering)問題,以保證應用層接收到的數據不會因為網絡上的傳輸問題而亂序(TCP會用這個順序號碼來拼接數據),32bit。
(4) Acknowledgment Number(確認號碼,ack):是數據接收方期望收到發送方在下一個報文段的順序號碼(Seq),因此確認號碼應當是上次已成功收到順序號碼(Seq)加1,32bit。
(5) Offset(TCP報文頭長度):用於存儲報文頭中有多少個32bit(上圖的一行),存儲長度為4bit,最大可表示(2^3+2^2+2^1+1)*32bit=60bytes的報文頭。最小取值5,5*32bit=20bytes。
(6) Reserved(保留):6bit, 均為0
(7) TCP Flags(TCP標誌位)每個長度均為1bit
CWR:壓縮,TCP Flags值0x80。
ECE:擁塞,0x40。
URG:緊急,0x20。當URG=1時,表示報文段中有緊急數據,應盡快傳送。
ACK:確認,0x10。當ACK = 1時,代表這是一個確認的TCP包,取值0則不是確認包。
PSH:推送,0x08。當發送端PSH=1時,接收端盡快的交付給應用進程。
RST:復位,0x04。當RST=1時,表明TCP連接中出現嚴重差錯,必須釋放連接,再重新建立連接。
SYN:同步,0x02。在建立連接是用來同步序號。SYN=1, ACK=0表示一個連接請求報文段。SYN=1,ACK=1表示同意建立連接。
FIN:終止,0x01。當FIN=1時,表明此報文段的發送端的數據已經發送完畢,並要求釋放傳輸連接。
(8) 窗口:用來控制對方發送的數據量,通知發放已確定的發送窗口上限。
(9) 檢驗和:該字段檢驗的範圍包括頭部和數據這兩部分。由發端計算和存儲,並由收端進行驗證。
(10) 緊急指針:緊急指針在URG=1時才有效,它指出本報文段中的緊急數據的字節數。
(11) TCP選項:長度可變,最長可達40字節

備註:ISN(Inital Sequence Number):初始化Sequence Number,發生在建立連接時。

2、TCP協議中的三次握手和四次揮手

技術分享

特別註意

Seq:是發送方當前報文的順序號碼。
ack:是發送方期望對方在下次返回報文中給回的Seq。

建立連接需要三次握手

第一次握手:客戶端向服務端發送連接請求包,標誌位SYN(同步序號)置為1,順序號碼為X=0。

第二次握手:服務端收到客戶端發過來報文,由SYN=1知道客戶端要求建立聯機,則為這次連接分配資源。並向客戶端發送一個SYN和ACK都置為1的TCP報文,設置初始順序號碼Y=0,將確認序號(ack)設置為上一次客戶端發送過來的順序號(Seq)加1,即X+1 = 0+1=1。

第三次握手:客戶端收到服務端發來的包後檢查確認號碼(ack)是否正確,即第一次發送的Seq加1(X+1=1)。以及標誌位ACK是否為1。若正確,服務端再次發送確認包,ACK標誌位為1,SYN標誌位為0。確認號碼(ack)=Y+1=0+1=1,發送順序號碼(Seq)為X+1=1。Server收到後確認號碼值與ACK=1則連接建立成功,可以傳送數據了。

斷開連接需要四次揮手

提醒:中斷連接端可以是Client端,也可以是Server端。只要將下面兩角色互換即可。
第一次揮手:客戶端給服務端發送FIN報文,用來關閉客戶端到服務端的數據傳送。將標誌位FIN和ACK置為1,順序號碼為X=1,確認號碼為Z=1。意思是說”我Client端沒有數據要發給你了,但是如果你還有數據沒有發送完成,則不必急著關閉Socket,可以繼續發送數據。所以你先發送ACK過來。”

第二次揮手:服務端收到FIN後,發回一個ACK(標誌位ACK=1),確認號碼為收到的順序號碼加1,即X=X+1=2。順序號碼為收到的確認號碼=Z。意思是說“你的FIN請求我收到了,但是我還沒準備好,請繼續你等我的消息" 這個時候客戶端就進入FIN_WAIT狀態,繼續等待服務端的FIN報文。

第三次揮手:當服務端確定數據已發送完成,則向客戶端發送FIN報文,關閉與客戶端的連接。標誌位FIN和ACK置為1,順序號碼為Y=1,確認號碼為X=2。意思是告訴Client端“好了,我這邊數據發完了,準備好關閉連接了。”

第四次揮手:客戶端收到服務器發送的FIN之後,發回ACK確認(標誌位ACK=1),確認號碼為收到的順序號碼加1,即Y+1=2。順序號碼為收到的確認號碼X=2。意思是“我Client端知道可以關閉連接了,但是我還是不相信網絡,怕 Server端不知道要關閉,所以發送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。Client端等待了2MSL後依然沒有收到回復,則證明Server端已正常關閉,那好,我Client端也可以關閉連接了。“(在TIME_WAIT狀態中,如果TCP client端最後一次發送的ACK丟失了,它將重新發送。TIME_WAIT狀態中所需要的時間是依賴於實現方法的。典型的值為30秒、1分鐘和2分鐘。等待之後連接正式關閉,並且所有的資源(包括端口號)都被釋放。)

為什麽關閉的時候卻是四次揮(握)手?
因為當Server端收到Client端的SYN連接請求報文後,可以直接發送SYN+ACK報文。其中ACK報文是用來應答的,SYN報文是用來同步的。但是關閉連接時,當Server端收到FIN報文時,很可能並不會立即關閉SOCKET,所以只能先回復一個ACK報文,告訴Client端,"你發的FIN報文我收到了"。只有等到我Server端所有的報文都發送完了,我才能發送FIN報文,因此不能一起發送。故需要四步握手。

3、TCP報文抓取工具:Wireshark

捕獲過濾器中填入表達式:host www.cnblogs.com and port 80(80等效於http)
有多個TCP流時在顯示過濾器中填入表達式:tcp.stream eq 0 篩選出第一個TCP流(包含完整的一次TCP連接:三次握手和四次揮手)

技術分享

技術分享

每條記錄都有如下協議層
(1) Frame: 物理層的數據幀概況
(2)Ethernet II: 數據鏈路層以太網幀頭部信息
(3) Internet Protocol Version 4: 互聯網層IP包頭部信息
(4)Transmission Control Protocol: 傳輸層的數據段頭部信息,此處是TCP
(5) Hypertext Transfer Protocol: 應用層的信息,此處是HTTP協議

技術分享

三、HTTP(HyperText Transfer Protocol,超文本傳輸協議)

HTTP是一個應用層協議,雖然在2015年已推出HTTP/2版本,並被主要的web瀏覽器和web服務器支持。但目前使用最廣泛的還是HTTP/1.1版本。有關歷史請查閱這裏。
它的主要特點可概括如下:

  • 支持客戶/服務器模式。
  • 簡單快速:客戶向服務器請求服務時,只需傳送請求方法和路徑。由於HTTP協議簡單,使得HTTP服務器的程序規模小,因而通信速度很快。
  • 靈活:HTTP允許傳輸任意類型的數據對象。正在傳輸的類型由Content-Type加以標記。
  • 無連接:無連接的含義是限制每次連接只處理一個請求。服務器處理完客戶的請求,並收到客戶的應答後,即斷開連接。采用這種方式可以節省傳輸時間。
  • 無狀態:HTTP協議是無狀態協議。無狀態是指協議對於事務處理沒有記憶能力。缺少狀態意味著如果後續處理需要前面的信息,則它必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它的應答就較快。為了解決這個問題, Web程序引入了Cookie機制來維護狀態。

另外,HTTP請求報文和響應報文都是由開始行(對於請求消息,開始行就是請求行,對於響應消息,開始行就是狀態行),消息報頭(可選),空行(只有CRLF的行),消息正文(可選)組成。將在下面詳細講解。

1、請求報文結構

報文中的數據都使用ASCII編碼,各個字段的長度是不確定的(除了作為結尾的CRLF外,不允許出現單獨的CR或LF字符)。

技術分享

2、請求報文樣例

技術分享
POST /search HTTP/1.1  
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint, 
application/msword, application/x-silverlight, application/x-shockwave-flash, */*  
Referer: http://www.google.cn/  
Accept-Language: zh-cn  
Accept-Encoding: gzip, deflate  
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)  
Host: www.google.cn 
Connection: Keep-Alive  
Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g; 
NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
FxlRugatx63JLv7CWMD6UB_O_r  

hl=zh-CN&source=hp&q=domety  
技術分享

3、請求報文參數詳解

請求方法

所有請求方法名稱全為大寫,目前有9種:
技術分享
備註
安全性:https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol
冪等性:表示的操作至多只會被處理一次,每次調用都將返回第一次調用時的處理結果。
關於HTTP請求GET和POST的區別
(1).提交形式:
GET提交的數據會放在URL之後,以?分割URL和傳輸數據,參數之間以&相連,如EditPosts.aspx?name=test1&id=123456. POST方法是把提交的數據放在HTTP包的Body中.
(2).傳輸數據的大小:
HTTP協議本身沒有對傳輸的數據大小進行限制,HTTP協議規範也沒有對URL長度進行限制。 而在實際開發中存在的限制主要有:
GET:特定瀏覽器和服務器對URL長度有限制,例如IE對URL長度的限制是2083字節(2K+35)。對於其他瀏覽器,如Netscape、FireFox等,理論上沒有長度限制,其限制取決於操作系統的支持。
因此對於GET提交時,傳輸數據就會受到URL長度的限制。
POST:由於不是通過URL傳值,理論上數據不受限。但實際各個WEB服務器會規定對post提交數據大小進行限制,Apache、IIS6都有各自的配置。
(3).安全性:
POST的安全性要比GET的安全性高,具有真正的Security的含義。而且通過GET提交數據,用戶名和密碼將明文出現在URL上,因為登錄頁面有可能被瀏覽器緩存,其他用戶瀏覽歷史紀錄就可以拿到賬號和密碼了。

請求報頭域

報頭域指頭部中的Key,且不分大小寫。

技術分享

4、響應報文結構

如所見,響應報文結構與請求報文結構唯一真正的區別在於第一行中用狀態信息代替了請求信息。狀態行(status line)通過提供一個狀態碼來說明所請求的資源情況。

技術分享

5、響應報文樣例

技術分享
HTTP/1.1 200 OK
Date: Mon, 23 May 2005 22:38:34 GMT
Content-Type: text/html; charset=UTF-8
Content-Encoding: UTF-8
Content-Length: 138
Last-Modified: Wed, 08 Jan 2003 23:11:55 GMT
Server: Apache/1.3.3.7 (Unix) (Red-Hat/Linux)
ETag: "3f80f-1b6-3e1cb03b"
Accept-Ranges: bytes
Connection: close

<html>
<head>
  <title>An Example Page</title>
</head>
<body>
  Hello World, this is a very simple HTML document.
</body>
</html>
技術分享

6、響應報文參數詳解

響應狀態碼

狀態代碼由三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。
1xx:指示信息--表示請求已接收,繼續處理。
2xx:成功--表示請求已被成功接收、理解、接受。
3xx:重定向--要完成請求必須進行更進一步的操作。
4xx:客戶端錯誤--請求有語法錯誤或請求無法實現。
5xx:服務器端錯誤--服務器未能實現合法的請求。
常用狀態碼:

200 OK:成功返回狀態,對應,GET,PUT,PATCH,DELETE。
201 created - 成功創建。
302 Found:重定向,新的URL會在response中的Location中返回,瀏覽器將會使用新的URL發出新的Request。

例如在IE中輸入http://www.google.com. HTTP服務器會返回304, IE取到Response中Location header的新URL, 又重新發送了一 個 Request.
304 Not Modified:代表上次的文檔已經被緩存了, 還可以繼續使用。
400 bad request - 請求格式錯誤。
401 unauthorized - 未授權。
403 forbidden - 鑒權成功,但是該用戶沒有權限。
404 not found - 請求的資源不存在。
405 method not allowed - 該http方法不被允許。
410 gone - 這個url對應的資源現在不可用。
415 unsupported media type - 請求類型錯誤。
422 unprocessable entity - 校驗錯誤時用。
429 too many request - 請求過多。
500 Internal Server Error:服務器發生了不可預期的錯誤。
503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間後可能恢復正常。

其它狀態碼請查閱:https://en.wikipedia.org/wiki/List_of_HTTP_status_codes

響應報頭域

報頭域指頭部中的Key,且不分大小寫。

技術分享

7、HTTP報文抓取工具

Wireshark、Fiddler、HttpWatch(需結合IE)、Telnet
Wireshark:
在顯示過濾器中填入表達式:http and ip.addr == 42.121.252.58 and tcp.port == 80 過濾出http的響應和請求流程

技術分享

8、Session和Cookie

說到HTTP,就不得不提Session和Cookie。但嚴格來說,Session和Cookie並不是http協議的一部分。由於HTTP協議設計原則是無狀態的,但是近年來出現了種種需求,其中cookie的作用就是為了解決HTTP協議無狀態的缺陷所作出的努力。後來出現的session機制則是又一種在客戶端與服務器之間保持狀態的解決方案。 具體來說cookie機制采用的是在客戶端保持狀態的方案,而session機制采用的是在服務器端保持狀態的方案。同時我們也看到,由於采用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要借助於cookie機制來達到保存標識的目的,但實際上它還有其他選擇。

Session

Session是可以存儲針對於某一個用戶的瀏覽器以及通過其當前窗口打開的任何窗口具有針對性的用戶信息存儲機制。
通常大家認為,只要關閉瀏覽器,session就消失,其實這是錯誤的理解。對session來說也是一樣的,除非程序通知服務器刪除一個session,否則服務器會一直保留。由於關閉瀏覽器不會導致session被刪除,迫使服務器為seesion設置了一個失效時間,當距離客戶端上一次使用session的時間超過這個失效時間時,服務器就可以認為客戶端已經停止了活動,才會把session刪除以節省存儲空間.

(1)第一次訪問某個web站點資源時,客戶端提交沒有帶SessionID的請求(請求報文頭沒有Cookie頭域信息)。
而web服務器會檢查是否有SessionID過來,沒有則創建SessionID,並根據web程序自身定義在請求哪個資源時添加屬於當前會話的信息(也可為空),這個信息列表以SessionID作為標識。然後將SessionID返回給客戶端(通過響應報文頭的Set-Cookie頭域)。
(2 )客戶端再次訪問同個web站點時,提交帶有SessionID的請求(通過Cookie頭域存儲SessionID)。由服務端判斷session是否失效,如果未失效,可查詢屬於當前會話的信息列表。如果失效,則創建新的session(產生新的SessionID),而原先的session(包含session帶的信息列表)則丟失,無法訪問。

技術分享

技術分享

Cookie

保存SessionID的方式可以采用Cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個SessionID發回給服務器。Cookie的命名方式類似於SessionID。有時Cookie被人為的禁止,所以出現了其他機制以便在Cookie被禁止時仍然能夠把SessionID傳遞回服務器。這種技術叫做URL重寫,就是把SessionID直接附加在URL路徑的後面,附加方式也有兩種,一種是作為URL路徑的附加信息,表現形式為http://www.wantsoft.com/index.asp;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 。
另一種是作為查詢字符串附加在URL後面,表現形式為http://www.wantsoft.com/index?js ... 99zWpBng!-145788764 。

四、相關資料

  • 《系統架構設計師教程》
  • 《C#網絡應用編程》(第2版)
  • TCP 的那些事兒(上)
  • TCP協議中的三次握手和四次揮手(圖解)
  • HTTP 協議詳解
  • HTTP請求報文和HTTP響應報文
  • HTTP協議之Session和Cookie

網絡協議詳解