記一記 TCP的三握四揮

文章目錄


轉自如下兩篇文章:

TCP的三次握手與四次揮手理解及面試題(很全面)
面試官,不要再問我三次握手和四次揮手

每次看了TCP的三次握手和四次揮手,總是過一段時間就忘記了,寫此文加深理解和記憶。

如下圖所示,TCP首部中有很多信息,在這裏我們需要關注的是 序號確認號ACK, SYN, FIN標誌位
在這裏插入圖片描述

  • ISN(Initial Sequence Number):初始序列號。
  • ACK(確認字符,Acknowledge Character):佔1位,僅當ACK=1時,確認號字段纔有效。ACK=0時,確認號無效。
  • SYN(同步序列編號,Synchronize Sequence Numbers):是TCP/IP建立連接時使用的握手信號。當SYN=1,ACK=0時表示:這是一個連接請求報文段。若同意連接,則在響應報文段中使得SYN=1,ACK=1。因此,SYN=1表示這是一個連接請求,或連接接受報文。SYN這個標誌位只有在TCP建產連接時纔會被置1,握手完成後SYN標誌位被置0。
  • FIN:用來釋放一個連接。FIN=1表示:此報文段的發送方的數據已經發送完畢,並要求釋放傳輸連接。
  • 序號 seq:佔4個字節,用來標記數據段的順序,TCP把連接中發送的所有數據字節都編上一個序號,第一個字節的編號(ISN)由本地隨機產生;給字節編上序號後,就給每一個報文段指派一個序號;序列號seq就是這個報文段中的第一個字節的數據編號。有了序號才知道傳輸的數據的順序,在服務端才能正確組裝信息。
  • 確認號 ack:佔4個字節,期待收到對方下一個報文段的第一個數據字節的序號;確認號指的是期望接收到下一個字節的編號;因此當前報文段最後一個字節的編號+1即爲確認號。
    PS:ACK、SYN和FIN這些大寫的單詞表示標誌位,其值要麼是1,要麼是0;ack、seq小寫的單詞表示序號。

下圖表表示了各標誌位的含義:
在這裏插入圖片描述
三次握手:

  • 第一次握手:客戶端給服務端發一個 SYN 報文,並指明客戶端的初始化序列號 ISN。此時客戶端處於 SYN_SENT 狀態。

首部的同步位SYN=1,初始序號seq=x,SYN=1的報文段不能攜帶數據,但要消耗掉一個序號。

  • 第二次握手:服務器收到客戶端的 SYN 報文之後,會以自己的 SYN 報文作爲應答,並且也指定了自己的初始化序列號 ISN(s)。同時會把客戶端的 ISN + 1 作爲ACK 的值,表示自己已經收到了客戶端的 SYN,此時服務器處於 SYN_RCVD 的狀態。這次握手實際做了兩件事,一是告訴客戶端收到了其SYN包,二是發送自己的SYN包來請求連接。

在確認報文段中SYN=1,ACK=1,確認號ack=x+1,初始序號seq=y。

  • 第三次握手:客戶端收到 SYN 報文之後,會發送一個 ACK 報文,當然,也是一樣把服務器的 ISN + 1 作爲 ACK 的值,表示已經收到了服務端的 SYN 報文,此時客戶端處於 ESTABLISHED 狀態。服務器收到 ACK 報文之後,也處於 ESTABLISHED狀態,此時,雙方已建立起了連接。

確認報文段ACK=1,確認號ack=y+1,序號seq=x+1(初始爲seq=x,第二個報文段所以要+1),ACK報文段可以攜帶數據,不攜帶數據則不消耗序號。

在這裏插入圖片描述
四次揮手:

  • 第一次揮手:客戶端發送一個 FIN 報文,報文中會指定一個序列號。此時客戶端處於 FIN_WAIT_1 狀態。
    即發出連接釋放報文段(FIN=1,序號seq=u),並停止再發送數據,主動關閉TCP連接,進入FIN_WAIT_1(終止等待1)狀態,等待服務端的確認。
  • 第二次揮手:服務端收到FIN之後,會發送 ACK報文,且把客戶端的序列號值 +1 作爲 ACK報文的序列號值,表明已經收到客戶端的報文了,此時服務端處於 CLOSE_WAIT 狀態。即服務端收到連接釋放報文段後即發出確認報文段(ACK=1,確認號ack=u+1,序號seq=v),服務端進入CLOSE_WAIT(關閉等待)狀態,此時的TCP處於半關閉狀態,客戶端到服務端的連接釋放。客戶端收到服務端的確認後,進入FIN_WAIT_2(終止等待2)狀態,等待服務端發出的連接釋放報文段。
  • 第三次揮手:如果服務端也想斷開連接了,和客戶端的第一次揮手一樣,發給 FIN 報文,且指定一個序列號。此時服務端處於 LAST_ACK 的狀態。即服務端沒有要向客戶端發出的數據,服務端發出連接釋放報文段(FIN=1,ACK=1,序號seq=w,確認號ack=u+1),服務端進入LAST_ACK(最後確認)狀態,等待客戶端的確認。
  • 第四次揮手:客戶端收到 FIN 之後,一樣發送一個ACK 報文作爲應答,且把服務端的序列號值 +1 作爲自己 ACK 報文的序列號值,此時客戶端處於 TIME_WAIT 狀態。需要過一陣子以確保服務端收到自己的 ACK 報文之後纔會進入 CLOSED 狀態,服務端收到 ACK 報文之後,就處於關閉連接了,處於 CLOSED 狀態。
    即客戶端收到服務端的連接釋放報文段後,對此發出確認報文段(ACK=1,seq=u+1,ack=w+1),客戶端進入TIME_WAIT(時間等待)狀態。此時TCP未釋放掉,需要經過時間等待計時器設置的時間2MSL後,客戶端才進入CLOSED狀態。

在這裏插入圖片描述

嘗試回答下面的問題來確認是否真的理解了。

  1. 爲什麼需要三次握手,兩次不行嗎?
  2. 什麼是半連接隊列?
  3. ISN(Initial Sequence Number)是固定的嗎?
  4. 三次握手過程中可以攜帶數據嗎?
  5. SYN攻擊是什麼?
  6. 爲什麼連接的時候是三次握手,關閉的時候卻是四次握手?
  7. 爲什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
  8. 如果已經建立了連接,但是客戶端突然出現故障了怎麼辦?

這些問題的答案見 :

TCP的三次握手與四次揮手理解及面試題(很全面)
面試官,不要再問我三次握手和四次揮手

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章