TCP 三次握手、四次揮手過程


TCP 三次握手、四次揮手過程

關於 TCP 的握手及揮手過程有點模糊。這里回顧下。

1、TCP報文字段含義

(1)seq:序號,用來標記數據段的順序,TCP 把連接中發送的所有數據字節都編上一個序號,第一個字節的編號由本地隨機產生。

(2)ack:確認號,是期望收到對方的下一個報文段的數據的第一個字節的seq序號;只有 ACK 標志位為1時,確認序號字段才有效,ack = seq+1。

(3)標志位:6個標志位,URG、ACK、PSH、RST、SYN、FIN(置1時有效)。

  • URG:緊急指針有效。
  • ACK:確認序號有效。
  • PSH:接收方應該盡快將這個報文交給應用層。
  • RST:復位,對方要求重新建立連接。
  • SYN:表示一個連接請求連接接收報文。
  • FIN: 釋放一個連接。

2、三次握手(建立連接)

20200417105649525

(1)第一次握手:

客戶端主動向服務端發送請求建立連接的報文,並進入同步已發送狀態;SYN = 1 表示連接請求,seq = x 表示起始序列號,x表示一個隨機數,通常為1。(SYN=1,seq=x)

(2)第二次握手:

服務端收到客戶端的報文之后,返回一段確認接收到請求報文並同意創建新連接的報文,並進入同步收到狀態。(SYN=1, ACK=1, seq=y, ack=x+1)

(3)第三次握手:

客戶端接收到服務端的確認報文之后,也返回一段確認報文給服務端表示自己已收到確認報文並進入建立連接狀態,服務端收到確認報文后也進入建立連接狀態,此時雙方成功建立 TCP 連接。(ACK=1, seq=x+1, ack=y+1)

:雙方的確認號 ack 和序號 seq 的值,都是在彼此 ack 和 seq 值的基礎上進行計算的,這樣做保證了 TCP 報文傳輸的連貫性。一旦出現某一方發出的 TCP 報文丟失,便無法繼續"握手",以此確保了"三次握手"的順利完成。

3、四次揮手(斷開連接)

20200417105751660

(1)第一次揮手:

數據傳輸完畢,客戶端想要釋放連接(沒有數據需要傳輸給服務端了),於是向服務端發送一段 TCP 報文請求釋放連接,然后進入終止等待狀態一。並且停止在客戶端到服務端方向上發送數據,但是客戶端仍然能接收從服務端傳輸過來的數據。FIN=1 表示請求釋放連接, u為隨機生成的起始報文段序號(FIN=1,seq=u)

(2)第二次揮手:

服務端收到連接釋放報文,立即發出確認報文,表示接收到客戶端發送的釋放連接的請求,並進入關閉等待狀態。(ACK=1,seq=v,ack=u+1)

(3)第三次揮手:

服務端自從發出 ACK 確認報文之后,經過了關閉等待階段,做好了釋放服務器端到客戶端方向上的連接准備,再次向客戶端發出一段TCP報文表示已經准備好釋放連接了(沒有數據需要傳輸給客戶端了),然后進入最后確認狀態。(FIN=1,ACK=1,seq=w,ack=u+1)

(4)第四次揮手:

客戶端收到從服務器端發出的 TCP 報文,確認了服務器端已做好釋放連接的准備,於是再次向服務端發送報文表示接收到服務端准備好釋放連接的信號,並進入 TIME-WAIT 階段等待 2MSL ( 最大報文生存時間) 后再斷開連接,服務端收到最終確認報文后立即斷開連接,雙方斷開 TCP 連接。(ACK=1,seq=u+1,ack=w+1)

:與“三次揮手”一樣,在客戶端與服務器端傳輸的 TCP 報文中,雙方的確認號 ack 和序號 seq 的值,都是在彼此 ack 和 seq 值的基礎上進行計算的,這樣做保證了 TCP 報文傳輸的連貫性,一旦出現某一方發出的 TCP 報文丟失,便無法繼續"揮手",以此確保了"四次揮手"的順利完成。

4、常見面試題

1.為什么“握手”是三次,“揮手”卻要四次?

建立連接時,被動方服務器端結束 CLOSED 階段進入“握手”階段並不需要任何准備,可以一起返回 SYN 和 ACK 報文,開始建立連接。而釋放連接時,被動方服務端,然收到主動方客戶端釋放連接的請求時並不能立即釋放連接,因為還有必要的數據需要處理,所以服務器只能先先返回 ACK 確認收到報文,經過 CLOSE-WAIT 階段准備好釋放連接(處理完數據之后)之后,才能返回FIN釋放連接報文。

2.為什么客戶端在TIME-WAIT階段要等 2MSL?

主要目的是確認服務器端是否收到客戶端發出的最終 ACK 確認報文。
當客戶端發出最后的 ACK 確認報文時,並不能確定服務器端能夠收到該段報文。所以客戶端在發送完 ACK 確認報文之后,會設置一個時長為 2MSL 的計時器。MSL 指的是:一段TCP報文在傳輸過程中的最大生命周期。2MSL 即是一個發送和一個回復所需的最大時間。

服務端如果在 1MSL 內沒有收到客戶端發出的最終 ACK確認 報文(說明最終確認報文丟失了),就會再次向客戶端發出 FIN 報文。

如果客戶端在 2MSL 內,再次收到了來自服務器端的 FIN 報文,說明服務器端由於各種原因沒有接收到客戶端發出的 ACK 確認報文。客戶端再次向服務器端發出 ACK 確認報文,計時器重置,重新開始 2MSL 的計時。

所以,客戶端要經歷時長為 2MSL 的 TIME-WAIT 階段;這也是為什么客戶端比服務器端晚進入 CLOSED 階段的原因。

3.如果只有兩次握手會發生什么?

服務端可能收到已失效的連接請求報文段,之后傻傻等待,浪費資源。

“已失效的連接請求報文段”產生在這樣一種情況下:
客戶端發出的第一個連接請求報文段並沒有丟失,而是在某個網絡結點長時間的滯留了,以致延誤到連接釋放以后的某個時間才到達服務端。本來這是一個早已失效的報文段,但服務端收到此失效的連接請求報文段后,就誤認為是客戶端再次發出的一個新的連接請求。於是就向客戶端發出確認報文段,同意建立連接。

假設不采用“三次握手”,那么只要服務端發出確認,新的連接就建立了。由於現在客戶端並沒有發出建立連接的請求,因此不會理睬服務端的確認,也不會向服務發送數據包,而此時服務端在等待客戶端給它發送數據,造成資源浪費。

注:超時重傳,客戶端發送建立連接請求時,若服務端一定時間內沒有應答,則會再次發送相同請求,導致已失效的連接請求報文段被服務端接收的情況發生。

4.如果已經建立了連接,但是客戶端突然出現故障了怎么辦?

TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求后都會重新復位這個計時器,時間通常是設置為2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以后每隔75秒發送一次。若一連發送10個探測報文仍然沒反應,服務器就認為客戶端出了故障,接着就關閉連接。

參考資料:https://blog.csdn.net/CC_Together/article/details/105575364


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM