計算機網絡傳輸層---TCP連接的建立和終止(詳解三次握手四次揮手)

計算機網絡傳輸層—TCP連接的建立和終止(詳解三次握手四次揮手)

TCP 是面向連接的、可靠的、基於字節流的傳輸層通信協議。

TCP的特點:
  • TCP提供客戶與服務器之間的連接,是基於連接的數據傳輸協議,因此是一對一
  • TCP提供可靠性,數據可以無差錯、不丟失、不重複、按需到達
  • TCP提供擁塞控制和流量控制,保證數據傳輸的安全性
  • TCP是全雙工的,在一個連接上的任意時刻在進出兩個方向上既可以發送數據也可以接收數據
  • TCP 首部長度較長,會有一定的開銷,首部在沒有使用「選項」字段時是 20 個字節
TCP的頭部格式:

  • 源端口和目標端口號:用於多路複用和多路分解來自上層應用的數據
  • 序列號:序列號是實現可靠性的關鍵。在建立連接時由計算機生成的隨機數作爲其初始值,通過 SYN 包傳給接收端主機,每個數據包都有響應的序列號,用於標識該數據包,從而實現有序、不重複、重發等機制。
  • 確認應答號:指下一次「期望」收到的數據的序列號,發送端收到這個確認應答以後可以認爲在這個序號以前的數據都已經被正常接收。也是實現可靠性傳輸的關鍵
  • ACK:該位爲 1 時,表示 確認應答的字段爲有效
  • RST:該位爲 1時,表示 TCP 連接中出現異常必須強制斷開連接
  • SYN:該位爲 1 時,表示是要建立連接,進行初始化序列號,在其 序列號的字段進行序列號初始值的設定
  • FIN:該位爲 1 時,表示發送方不再進行數據發送,要斷開連接
  • 窗口大小:實現流量控制的關鍵,發送方根據收到的窗口大小的值調整自己的發送速率
  • 校驗和:由發送端填充,接收端對tcp報文段執行CRC算法以檢驗TCP報文段在傳輸過程中是否損壞
TCP三次握手

TCP通過三次握手建立連接,通過三次握手雙方確認序列號、窗口大小等信息

在這裏插入圖片描述
三次握手的流程:

  • 客戶端向服務器發送一個TCP報文,該報文不包含應用層數據。其中該 報文的SYN位 置爲1,然後客戶端的操作系統會隨機初始化一個序列號,將該序列號放置到TCP報文的序列號字段中。
  • 服務器收到該報文後,提取出序列號報文段,然後爲該TCP連接分配緩存和變量,然後向客戶端發送一個確認連接的TCP報文。該報文的SYN位 置爲1,ACK位 置爲1,其中序列號字段填充服務器生成的隨機序列號,ACK段填充的是客戶發的數據包的序列號+1。該報文不包含應用層數據
  • 客戶端收到服務器的SYNACK報文後,客戶爲該連接分配資源。客戶端向服務器發送TCP報文,其中ACK置爲1,確認應答號爲服務器的序列號+1,序列號爲客戶端的序列號+1.注意SYN位 置爲0,該數據包可以攜帶應用層數據信息。

三次握手建立後雙方將處於建立連接狀態。

從網絡編程的角度再次解析該過程:
在這裏插入圖片描述

  • 開始三次握手前,服務器需要處於準備好接收外界連接的狀態。因此需要調用socket、bind、listen三個函數,完成套接字的打開、綁定端口、監聽,服務器處於被動打開
  • 客戶通過connect發起主動打開,客戶TCP發送一個SYN報文,填充了隨機初始化的序列號,告知服務器該連接的初始序列號。
  • 服務器收到客戶端的SYN報文後,需要確認客戶的SYN,併發送自己的SYN。因此發送的數據包中有自己隨機初始化的SYN,以及對客戶SYN的確認ACK(客戶的SYN+1)
  • 客戶收到後將發送ACK確認服務器的SYN
爲什麼採用三次握手?
  • 三次握手可以阻止歷史重複連接的初始化 (兩次握手沒辦法避免歷史重複連接的干擾)
  • 三次握手可以同步雙方的初始序列號 (TCP是全雙工,因此同步雙方序列號至少需要三次握手)
  • 三次握手可以避免資源浪費
TCP四次揮手

TCP通過四次揮手完全關閉連接並釋放資源。值得注意的是,TCP連接的任意一方都可以主動請求終止該連接

在這裏插入圖片描述

四次揮手的過程: 以客戶端關閉連接爲例

  • 客戶端沒有數據要再發送,想要關閉連接,因此發送一個特殊的TCP報文,該報文的FIN位 置爲1,表示是終止連接報文。
  • 服務器收到該報文後向客戶端發送ACK確認該終止報文已收到,服務器進入CLOSED_WAIT’狀態
  • 此時,該TCP連接中,服務器仍可以向客戶端發送數據
  • 服務器發送完數據後,也申請終止連接。向客戶端發送一個FIN報文,其中FIN 置爲1
  • 客戶端收到後向服務器發送一個ACK表示收到,客戶端進入TIME_WAIT 狀態
  • 服務器收到ACK後將進入關閉狀態,服務器的該連接的資源進行釋放
  • 客戶端經過 2MSL 時間後進入關閉狀態, 釋放該連接的資源

從網絡編程的角度再次分析四次揮手:
在這裏插入圖片描述

  • 某個進程首先調用close函數,我們稱該端爲主動關閉,該端TCP發送一個FIN包,表示數據發送完畢
  • 接收到FIN的另一端執行被動關閉,該端返回一個ACK。接收到FIN表示接收端應用進程在該連接上無額外數據可接收
  • 一段時間後,另一端發送數據完畢,調用close關閉套接字,因此它也發送一個FIN包
  • 接收到這個FIN包的端(主動關閉端)需要發送一個ACK確認該FIN

需要注意的是,在TCP斷開連接時,存在一個半關閉狀態,即雖然停止了接收數據但是仍然在發送數據。

TCP連接的整體圖示:

在這裏插入圖片描述

TCP狀態轉移圖:

在一個TCP連接的聲明週期中,運行在每臺主機上的TCP協議會在各種狀態之間變遷。

客戶TCP的典型狀態變遷:
在這裏插入圖片描述

服務器端TCP的典型狀態變遷:
在這裏插入圖片描述

TIME_WAIT狀態

當主動方接收到被動方發來的FIN後,將進入TIME_WAIT狀態。TIME_WAIT 狀態的時間通常是最長分節生命期(MSL)的兩倍,通常稱爲2MSL。

TCP實現時必須爲MSL設置一個值,通常是1分鐘到4分鐘左右,MSL是任何IP數據報能夠在因特網中存活的最長時間。

爲什麼需要 TIME_WAIT 狀態?

  • 可靠地實現TCP全雙工連接的終止(假如回覆的ACK服務器沒有收到,但是自己已經關閉連接,則服務器將一直髮送FIN直至一些機制觸發導致自己關閉,這將浪費服務器資源,使其無法正常關閉。爲了正確終止連接,必須正確處理終止序列中4個分節任意一個分節丟失的情況)
  • 允許老的重複分節在網絡中消逝 (經過兩個MSL,足以讓兩個方向上的數據包都被丟棄,使得原來連接的數據包在網絡中都自然消失,再出現的數據包一定都是新建立連接所產生的,防止來自某個連接的老的重複分組在該連接終止後再現,從而被誤解爲某個新連接的信息,導致錯誤)
TCP的套接字編程基本函數:
  • 服務端和客戶端初始化 socket,得到文件描述符;
  • 服務端調用 bind,將綁定在 IP 地址和端口; 調用 listen,進行監聽;調用 accept,等待客戶端連接;
  • 客戶端調用 connect,向服務器端的地址和端口發起連接請求;
  • 服務端 accept 返回用於傳輸的 socket 的文件描述符;
  • 客戶端調用 write 寫入數據;服務端調用 read 讀取數據;
  • 服務端調用 write 寫入數據;客戶端調用 read 讀取數據;
  • 客戶端斷開連接時,會調用 close,那麼服務端 read 讀取數據的時候,就會讀取到了 EOF,待處理完數據後,服務端調用 close,表示連接關閉

需要注意的是:客戶端 connect 成功返回是在第二次握手,服務端 accept 成功返回是在三次握手成功之後

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