天天看點

TCP/IP協定十七:三次握手和四次揮手 及 TCP連接配接狀态1. 三次握手1.2 三次握手過程1.3 為什麼需要三次握手,兩次不行嗎?原因:确認雙方的接收與發送能力是否正常2. 四次揮手3. 參考4. TCP連接配接狀态

TCP/IP協定十七:三次握手和四次揮手 及 TCP連接配接狀态

  • 1. 三次握手
    • 1.1 什麼是三次握手?
      • 1.1.1 定義:三個包
      • 1.1.2 作用:确認雙方的接收能力和發送能力是否正常,以及視窗大小等
  • 1.2 三次握手過程
  • 1.3 為什麼需要三次握手,兩次不行嗎?原因:确認雙方的接收與發送能力是否正常
    • 1.4 什麼是半連接配接隊列,全連接配接隊列?
    • 1.5 ISN(Initial Sequence Number) :随機産生的,很大的數
    • 1.6 三次握手過程中可以攜帶資料嗎?
  • 2. 四次揮手
    • 2.1 定義,半關閉
    • 2.2 四次揮手過程
    • 2.3 為什麼需要四次
    • 2.4 2MSL等待狀态
    • 2.5 四次揮手釋放連接配接時,等待2MSL的意義
    • 2.6 為什麼TIME_WAIT狀态需要經過2MSL才能傳回到CLOSE狀态
  • 3. 參考
  • 4. TCP連接配接狀态
    • 4.1 三次握手狀态
    • 4.2 四次揮手狀态

1. 三次握手

1.1 什麼是三次握手?

1.1.1 定義:三個包

(Three-way Handshake):其實就是指建立一個TCP連接配接時,需要用戶端和伺服器總共發送3個包。

1.1.2 作用:确認雙方的接收能力和發送能力是否正常,以及視窗大小等

進行三次握手的主要作用就是為了确認雙方的接收能力和發送能力是否正常、指定自己的初始化序列号為後面的可靠性傳送做準備。

實質上其實就是連接配接伺服器指定端口,建立TCP連接配接,并同步連接配接雙方的序列号和确認号,交換TCP視窗大小資訊。

1.2 三次握手過程

剛開始用戶端處于 Closed 的狀态,服務端處于 Listen 狀态。

進行三次握手:

  1. 第一次握手:用戶端給服務端發一個 SYN 封包,并指明用戶端的初始化序列号 ISN©。此時用戶端處于 SYN_SEND 狀态。

    首部的同步位SYN=1,初始序号seq=x(随機産生的,很大的數),SYN=1的封包段不能攜帶資料,但要消耗掉一個序号。

    2.第二次握手:伺服器收到用戶端的 SYN 封包之後,會以自己的 SYN 封包作為應答,并且也是指定了自己的初始化序列号 ISN(s)。同時會把用戶端的 ISN + 1 作為ACK 的值,表示自己已經收到了用戶端的 SYN,此時伺服器處于 SYN_REVD 的狀态。

    在确認封包段中SYN=1,ACK=1,确認号ack=x+1,初始序号seq=y(也是随機産生的,很大的數)。

    3.第三次握手:用戶端收到 SYN 封包之後,會發送一個 ACK 封包,當然,也是一樣把伺服器的 ISN + 1 作為 ACK 的值,表示已經收到了服務端的 SYN 封包,此時用戶端處于 ESTABLISHED 狀态。伺服器收到 ACK 封包之後,也處于 ESTABLISHED 狀态,此時,雙方已建立起了連接配接。

    确認封包段ACK=1,确認号ack=y+1,序号seq=x+1(初始為seq=x,第二個封包段是以要+1),ACK封包段可以攜帶資料,不攜帶資料則不消耗序号。

    TCP/IP協定十七:三次握手和四次揮手 及 TCP連接配接狀态1. 三次握手1.2 三次握手過程1.3 為什麼需要三次握手,兩次不行嗎?原因:确認雙方的接收與發送能力是否正常2. 四次揮手3. 參考4. TCP連接配接狀态

1.3 為什麼需要三次握手,兩次不行嗎?原因:确認雙方的接收與發送能力是否正常

弄清這個問題,我們需要先弄明白三次握手的目的是什麼,能不能隻用兩次握手來達到同樣的目的。

  1. 第一次握手:用戶端發送網絡包,服務端收到了。這樣服務端就能得出結論:用戶端的發送能力、服務端的接收能力是正常的。
  2. 第二次握手:服務端發包,用戶端收到了。

    這樣用戶端就能得出結論:服務端的接收、發送能力,用戶端的接收、發送能力是正常的。不過此時伺服器并不能确認用戶端的接收能力是否正常。

  3. 第三次握手:用戶端發包,服務端收到了。

    這樣服務端就能得出結論:用戶端的接收、發送能力正常,伺服器自己的發送、接收能力也正常。

    是以,需要三次握手才能确認雙方的接收與發送能力是否正常。

1.4 什麼是半連接配接隊列,全連接配接隊列?

半連接配接隊列:

  1. 伺服器第一次收到用戶端的 SYN 之後,就會處于 SYN_RCVD 狀态,此時雙方還沒有完全建立其連接配接,伺服器會把此種狀态下請求連接配接放在一個隊列裡,我們把這種隊列稱之為半連接配接隊列。

全連接配接隊列:

  1. 全連接配接隊列,就是已經完成三次握手,建立起連接配接的就會放在全連接配接隊列中。如果隊列滿了就有可能會出現丢包現象。

1.5 ISN(Initial Sequence Number) :随機産生的,很大的數

當一端為建立連接配接而發送它的SYN時,它為連接配接選擇一個初始序号。ISN随時間而變化,是以每個連接配接都将具有不同的ISN。ISN可以看作是一個32比特的計數器,每4ms加1 。這樣選擇序号的目的在于防止在網絡中被延遲的分組在以後又被傳送,而導緻某個連接配接的一方對它做錯誤的解釋。

三次握手的其中一個重要功能是用戶端和服務端交換 ISN(Initial Sequence Number),以便讓對方知道接下來接收資料的時候如何按序列号組裝資料。如果 ISN 是固定的,攻擊者很容易猜出後續的确認号,是以 ISN 是動态生成的。

1.6 三次握手過程中可以攜帶資料嗎?

其實第三次握手的時候,是可以攜帶資料的。但是,第一次、第二次握手不可以攜帶資料

為什麼這樣呢?大家可以想一個問題,假如第一次握手可以攜帶資料的話,如果有人要惡意攻擊伺服器,那他每次都在第一次握手中的 SYN 封包中放入大量的資料。因為攻擊者根本就不理伺服器的接收、發送能力是否正常,然後瘋狂着重複發 SYN 封包的話,這會讓伺服器花費很多時間、記憶體空間來接收這些封包。

也就是說,第一次握手不可以放資料,其中一個簡單的原因就是會讓伺服器更加容易受到攻擊了。而對于第三次的話,此時用戶端已經處于 ESTABLISHED 狀态。對于用戶端來說,他已經建立起連接配接了,并且也已經知道伺服器的接收、發送能力是正常的了,是以能攜帶資料也沒啥毛病。

2. 四次揮手

2.1 定義,半關閉

TCP 的連接配接的拆除需要發送四個包,是以稱為四次揮手(Four-way handshake),用戶端或伺服器均可主動發起揮手動作。

建立一個連接配接需要三次握手,而終止一個連接配接要經過四次揮手(也有将四次揮手叫做四次握手的)。這由TCP的半關閉(half-close)造成的。

所謂的半關閉,其實就是TCP提供了連接配接的一端在結束它的發送後還能接收來自另一端資料的能力。

2.2 四次揮手過程

剛開始雙方都處于 ESTABLISHED 狀态,假如是用戶端先發起關閉請求。四次揮手的過程如下:

  1. 第一次揮手:用戶端發送一個 FIN 封包,封包中會指定一個序列号。此時用戶端處于 FIN_WAIT1 狀态。

    即發出連接配接釋放封包段(FIN=1,序号seq=u),并停止再發送資料,主動關閉TCP連接配接,進入FIN_WAIT1(終止等待1)狀态,等待服務端的确認。

  2. 第二次揮手:服務端收到 FIN 之後,會發送 ACK 封包,且把用戶端的序列号值 +1 作為 ACK 封包的序列号值,表明已經收到用戶端的封包了,此時服務端處于 CLOSE_WAIT 狀态。

    即服務端收到連接配接釋放封包段後即發出确認封包段(ACK=1,确認号ack=u+1,序号seq=v),服務端進入CLOSE_WAIT(關閉等待)狀态,此時的TCP處于半關閉狀态,用戶端到服務端的連接配接釋放。用戶端收到服務端的确認後,進入FIN_WAIT2(終止等待2)狀态,等待服務端發出的連接配接釋放封包段。

  3. 第三次揮手:如果服務端也想斷開連接配接了,和用戶端的第一次揮手一樣,發給 FIN 封包,且指定一個序列号。此時服務端處于 LAST_ACK 的狀态。

    即服務端沒有要向用戶端發出的資料,服務端發出連接配接釋放封包段(FIN=1,ACK=1,序号seq=w,确認号ack=u+1),服務端進入LAST_ACK(最後确認)狀态,等待用戶端的确認。

  4. 第四次揮手:用戶端收到 FIN 之後,一樣發送一個 ACK 封包作為應答,且把服務端的序列号值 +1 作為自己 ACK 封包的序列号值,此時用戶端處于 TIME_WAIT 狀态。需要過一陣子以確定服務端收到自己的 ACK 封包之後才會進入 CLOSED 狀态,服務端收到 ACK 封包之後,就處于關閉連接配接了,處于 CLOSED 狀态。

    即用戶端收到服務端的連接配接釋放封包段後,對此發出确認封包段(ACK=1,seq=u+1,ack=w+1),用戶端進入TIME_WAIT(時間等待)狀态。此時TCP未釋放掉,需要經過時間等待計時器設定的時間2MSL後,用戶端才進入CLOSED狀态。

收到一個FIN隻意味着在這一方向上沒有資料流動。用戶端執行主動關閉并進入TIME_WAIT是正常的,服務端通常執行被動關閉,不會進入TIME_WAIT狀态。

TCP/IP協定十七:三次握手和四次揮手 及 TCP連接配接狀态1. 三次握手1.2 三次握手過程1.3 為什麼需要三次握手,兩次不行嗎?原因:确認雙方的接收與發送能力是否正常2. 四次揮手3. 參考4. TCP連接配接狀态

2.3 為什麼需要四次

  1. 因為當服務端收到用戶端的SYN連接配接請求封包後,可以直接發送SYN+ACK封包。其中ACK封包是用來應答的,SYN封包是用來同步的。
  2. 但是關閉連接配接時,當服務端收到FIN封包時,很可能并不會立即關閉SOCKET,是以隻能先回複一個ACK封包,告訴用戶端,“你發的FIN封包我收到了”。隻有等到我服務端所有的封包都發送完了,我才能發送FIN封包,是以不能一起發送。故需要四次揮手。

2.4 2MSL等待狀态

  1. TIME_WAIT狀态也成為2MSL等待狀态。每個具體TCP實作必須選擇一個封包段最大生存時間MSL(Maximum Segment Lifetime),它是任何封包段被丢棄前在網絡内的最長時間。這個時間是有限的,因為TCP封包段以IP資料報在網絡内傳輸,而IP資料報則有限制其生存時間的TTL字段。

2.5 四次揮手釋放連接配接時,等待2MSL的意義

兩個理由:

  1. 保證用戶端發送的最後一個ACK封包段能夠到達服務端。
  2. 防止“已失效的連接配接請求封包段”出現在本連接配接中。

2.6 為什麼TIME_WAIT狀态需要經過2MSL才能傳回到CLOSE狀态

理論上,四個封包都發送完畢,就可以直接進入CLOSE狀态了,但是可能網絡是不可靠的,有可能最後一個ACK丢失。是以TIME_WAIT狀态就是用來重發可能丢失的ACK封包。

3. 參考

https://www.cnblogs.com/heyonggang/p/11634228.html

《TCP/IP詳解 卷1:協定》

4. TCP連接配接狀态

4.1 三次握手狀态

client 			sever
closed			closed		起始
				listen		第一次握手
syn-sent		syn-rcvd	第二次握手
establisted		establisted	第三次握手
           
TCP/IP協定十七:三次握手和四次揮手 及 TCP連接配接狀态1. 三次握手1.2 三次握手過程1.3 為什麼需要三次握手,兩次不行嗎?原因:确認雙方的接收與發送能力是否正常2. 四次揮手3. 參考4. TCP連接配接狀态

4.2 四次揮手狀态

client 			sever
establisted		establisted		起始
FIN_WAIT1						第一次揮手
				close-wait		第二次揮手
FIN_WAIT2						第三次揮手
				last-ack		第四次揮手
time-wait		syn-rcvd	
closed			closed	
           
TCP/IP協定十七:三次握手和四次揮手 及 TCP連接配接狀态1. 三次握手1.2 三次握手過程1.3 為什麼需要三次握手,兩次不行嗎?原因:确認雙方的接收與發送能力是否正常2. 四次揮手3. 參考4. TCP連接配接狀态

繼續閱讀