1. 程式人生 > >生命是一場長跑,需要用一生去奮鬥,知恥而後勇!

生命是一場長跑,需要用一生去奮鬥,知恥而後勇!

目錄

一、網路協議

       國際標準化組織(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:伺服器當前不能處理客戶端的請求,一段時間後可能恢復正常。

響應報頭域

報頭域指頭部中的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 。

四、相關資料