TCP協議與UDP協議學習筆記

引子

今天正好是週末,剛好偶然翻到了之前學習計算機網絡的時候做的關於TCP協議、UDP協議的筆記。TCP三次握手、四次揮手又是面試中的高頻考點,正好自己最近也在準備各種面試,這裏就總結一下TCP協議和UDP協議相關的知識點。

TCP協議與UDP協議

TCP協議和UDP協議是運輸層的兩個主要協議。

  • TCP:Transmission Control Protocol,傳輸控制協議
  • UDP:User Datagram Protocol,用戶數據報協議

兩種協議對比:

TCP協議 UDP協議
面向連接:使用之前要建立連接,使用之後要釋放連接。 無連接,面向報文:使用之前不需要建立連接
提供可靠交付服務。使用TCP連接傳送的數據,無差錯、不丟失、不重複,並且有序。 使用 盡最大努力交付,不保證可靠交付。
每一條TCP連接只能有兩個端點,每一條TCP連接只能是 點對點 的。 UDP支持一對一、一對多、多對一和多對多的交互通信。
TCP有擁塞控制 UDP沒有擁塞控制
TCP首部 前20字節固定,後面的 4n 個字節的“選項”可根據需要增加 UDP首部開銷小,只有 8 字節。
TCP提供 全雙工通信  

TCP三次握手

首先介紹幾個關鍵詞:

  • seq:序號,Sequence Number。TCP連接傳輸的數據流中的每一個字節都按順序編號,首部中的序號字段指本報文段所發送數據的第一個字節的序號。
  • 確認號:期待收到對方下一個報文段的第一個數據字節的序號。在謝老師的書中用了小寫的 ack 表示。
  • ACK:確認位,ACKnowledgement。只有ACK=1的時候,確認號字段纔有效。
  • SYN:同步位,SYNchronization。在連接建立時用來同步序號。當SYN=1,並且ACK=0時,表明這是一個連接請求報文段。若對方同意連接,則在響應的報文段中使 SYN=1 和 ACK=1。因此,SYN=1 就表示這是一個連接請求或連接接受報文。
  • FIN:終止位,FINis。用來釋放一個連接,當 FIN=1 時,表明此報文段發送方的數據已經傳輸完畢,並要求釋放連接。

下面,我們來看看TCP三次握手的示意圖:

具體的流程:

剛開始客戶端和服務端都處於 CLOSED 狀態,而後服務端開啓,處於監聽(LISTEN)狀態,等待客戶端的請求。現在客戶端也開啓,準備請求連接。

  • 第一次握手:客戶端向服務端發送一個請求連接報文,報文首部中 同步位SYN=1,同時序號位 seq會被指定一個客戶端對應的初始值,這裏記爲 x。此時,客戶端進入 SYN-SENT 狀態。
  • 第二次握手:服務端收到請求報文後,如果同意連接,則向客戶端回覆確認。在確認報文中,同步位SYN和確認位ACK都被置爲1,同時將客戶端的序號 x 加1作爲確認號(ack=x+1),序號位seq也會被指定爲一個服務端對應的初始值,這裏記爲y。此時,服務端進入 SYN-RCVD 狀態。
  • 第三次握手:客戶端收到服務端的確認後,還要向服務端回覆確認。確認報文中,ACK被置爲1,同時將服務端的序號 y 加1作爲確認號(ack=y+1),並且將自己的序號位值 x 加1作爲新的序號位(seq=x+1)。回覆確認動作完成後,客戶端進入 ESTABLISHED 狀態,當服務端收到客戶端的確認後,服務端也會進入 ESTABLISHED 狀態。

理解了上面這個流程後,這裏有幾個問題:

1、爲什麼要三次握手?兩次不行麼?

  客戶端得到信息 服務端得到信息
第一次握手   客戶端發送正常,服務端接收正常
第二次握手 客戶端、服務端的發送、接收均正常  
第三次握手   客戶端、服務端的發送、接收均正常

三次握手的目的之一是 使雙方都能確認對方的存在,以及雙方的發送、接受功能都正常。如上面的表格:

  • 第一次握手後,服務端接收到客戶端的信息,服務端就能夠知道 客戶端的發送功能正常,以及服務端自身的接收功能正常。
  • 第二次握手後,客戶端收到服務端的確認消息,就能知道自己之前發送的消息服務端接收到了。客戶端就能夠知道 客戶端自己的發送、接收功能都正常,同時 服務端的發送、接收功能都正常。
  • 第三次握手後,服務端收到了客戶端的確認,就知道服務端自己回覆的確認消息客戶端收到了。服務端也就能知道 服務端自己以及客戶端的發送、接收功能都正常。

也就是,經過三次握手後,客戶端、服務端雙方纔能確保 雙方的發送、接收功能均正常,而兩次握手則不行。

對於第三次握手,需要再確認一次的目的是,爲了防止客戶端已失效的連接請求報文段突然又傳送到了服務端,因而產生錯誤。

比如,第一次握手時,客戶端的報文由於網絡等原因,在途中滯留了一段時間,以至於在連接釋放後纔到達服務端。服務端誤以爲這是一次新的連接請求,就回復確認。如果沒有第三次客戶端的確認,那在服務端回覆確認後,連接就建立了,然而客戶端並不理睬服務端的確認,服務端就會一直等待客戶端的數據。這樣就白白浪費了服務端資源。

2、有沒有可能“四次握手”?

如前面圖中,標了 草莓紅 的第二次握手階段,服務端在向客戶端回覆的確認報文段,可以拆成兩個報文段。

如上圖,服務端可以先發送一個確認報文段(ACK=1,ack = x+1),然後再發送一個同步報文段(SYN=1,seq=y)。這樣的過程就變成了四報文握手,但效果和三次握手是一樣的。

3、三次握手過程中,可以攜帶數據麼?

第三次握手時可以攜帶數據,第一次和第二次不行。

在TCP三次握手示意圖中,我標 藍色 的第三次握手可以攜帶數據。

TCP的標準規定:SYN報文段(即SYN=1的報文段)不能攜帶數據,而ACK報文段可以攜帶數據。如果ACK報文段不攜帶數據,則不消耗序號,否則需要消耗序號。

什麼意思呢?意思就是,如TCP三次握手示意圖,第三次握手時,序號seq=x+1。如果此時不攜帶數據,那下一個數據報文段的序號仍然爲 seq=x+1。如果此時攜帶了序號差爲 t 的數據,那下一個數據報文段的序號就要變爲 seq = x + 1 + t 。

從另一個角度,在第三次握手時,客戶端已經知道 客戶端自己和服務端 的發送、接收功能都正常了,所以攜帶數據也沒問題。

TCP四次揮手

上面請了TCP三次握手建立連接的過程,連接建立後,客戶端服務端開始傳遞數據,數據傳遞完後,需要進行TCP“四次揮手”才能將連接釋放掉。下面就講一講TCP四次揮手的過程。
 

具體的流程:

剛開是客戶端、服務端都處於 ESTABLISHED 狀態,並可以互傳數據。假設此時客戶端的數據已經傳遞完畢,準備關閉連接了。

  • 第一次揮手:客戶端向服務端發送連接釋放報文段,報文首部終止控制位 FIN=1,其序號記爲seq=u(假定前面客戶端已經發送的最後一個字節的序號是 u-1)。同時,客戶端進入 FIN-WAIT-1 狀態。
  • 第二次揮手:服務端收到客戶端的連接釋放報文後,會立即回覆確認。確認報文首部 ACK=1,並將客戶端的序號 u 加 1 作爲確認號(ack=u+1),同時序號記爲 seq=v(假定前面服務端已經發送的最後一個字節的序號是 v-1)。此時,服務端進入 CLOSE-WAIT 狀態。客戶端收到來自服務的確認後,就進入 FIN-WAIT-2 狀態。此時,服務端仍然可以向客戶端傳送數據。
  • 第三次揮手:當服務端向客戶端的數據傳送完畢後,服務端也要向客戶端發送連接釋放報文。報文首部終止控制位 FIN和確認位ACK都被置爲1,服務端還必須重複上次已經發送過的確認號 ack=u+1。同時,記現在的序號 seq=w(假定在客戶端釋放連接後,服務端又向客戶端發送了 序號差爲 w-v 的數據)。這時,服務端進入 LAST-ACK 狀態。
  • 第四次揮手:客戶端收到服務端的連接釋放報文段,會立即回覆確認。確認報文中,ACK=1,將服務端傳來的序號加1作爲確認號 ack=w+1,自己的序號也變爲 seq=u+1(客戶端發送的上一條報文的序號爲 u,即第一次揮手的報文)。此時,客戶端進入 TIME-WAIT 狀態。當服務端收到確認報文後,服務端進入 CLOSED狀態。

需要注意的是,上面第四次揮手,當客戶端回覆確認報文後,進入TIME_WAIT 狀態。此時,TCP連接仍然沒有被釋放。當客戶端回覆完確認報文後,需要在 TIME_WAIT 狀態等待一段時間(一般是2個最長報文段壽命,記爲 2MSL,建議1MSL=2分鐘),纔會進入 CLOSED 狀態。

這裏,又有幾個問題:

1、客戶端爲什麼必須要在 TIME_WAIT 狀態等待 2MSL 呢?

這裏有兩個理由:

  • 第一,保證客戶端發送的最後一個ACK報文能夠到達服務端。

這個ACK報文是有可能會丟失的,因而處在 LAST-ACK 狀態下的服務端收不到客戶端對已發送的 FIN+ACK 報文(第三次揮手)的確認。服務端會超時重傳這個 FIN+ACK 報文段,接着客戶端就能在 2MSL時間內收到這個重傳的 FIN+ACK 報文段。接着客戶端會重新回覆ACK確認報文,並且重新計時 2MSL。這樣,客戶端和服務端就能正常進入 CLOSED 狀態。

如果客戶端在 TIME_WAIT 狀態不等待,而是在發送完 ACK 報文後立即釋放連接,如果此ACK報文段丟失,那就收不到服務端重傳的 FIN+ACK報文,也就無法正常回復確認,這樣可能造成服務端一直等待確認,無法正常進入 CLOSED 狀態。

  • 第二,防止已失效的連接請求報文段出現在本連接中。

客戶端再發送完最後一個ACK報文段後,再經過2MSL,就可以使本連接持續時間內所產生的所有報文段都從網絡中消失。這樣,下一個新的連接中就不會出現舊的連接請求報文段。

總結

TCP三次握手、四次揮手面試也被問到過很多次了,自己也是看了很多次了。這一次,又仔細認真地對照着書籍學習了一遍,終於搞懂了其中序號、確認號的變化關係了。理解着去學習,又學到了很多。加油!

參考文檔

1、《計算機網絡》第七版,謝希仁 著,第五章

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