計算機網絡--TCP的三次握手和四次揮手

一篇寫得很細緻的博客:兩張動圖-徹底明白TCP的三次握手與四次揮手

TCP 在傳輸之前會進行三次溝通,一般稱爲「三次握手」,傳完數據斷開的時候要進行四次溝通,一般稱爲「四次揮手」。

爲了準確⽆誤地把數據送達⽬標處,TCP協議採⽤了三次握⼿策略。

一、數據包說明

  1. 源端口號( 16 位):它(連同源主機 IP 地址)標識源主機的一個應用進程。

  2. 目的端口號( 16 位):它(連同目的主機 IP 地址)標識目的主機的一個應用進程。
      這兩個值加上 IP 報頭中的源主機 IP 地址和目的主機 IP 地址唯一確定一個 TCP 連接。

  3. 順序號 seq( 32 位):用來標識從 TCP 源端向 TCP 目的端發送的數據字節流,它表示在這個報文段中的第一個數據字節的順序號
      如果將字節流看作在兩個應用程序間的單向流動,則TCP 用順序號對每個字節進行計數
      序號是 32bit 的無符號數,序號到達 2 的 32 次方 - 1 後又從 0 開始
      當建立一個新的連接時, SYN 標誌變 1 ,順序號字段包含由這個主機選擇的該連接的初始順序號 ISN ( Initial Sequence Number )。

  4. 確認號 ACK( 32 位):包含發送確認的一端所期望收到的下一個順序號
      因此,確認序號應當是上次已成功收到數據字節順序號加 1 。
      只有 ACK 標誌爲 1 時確認序號字段纔有效。
      TCP 爲應用層提供全雙工服務,這意味數據能在兩個方向上獨立地進行傳輸。
      因此,連接的每一端必須保持每個方向上的傳輸數據順序號。

  5. TCP 報頭長度( 4 位):給出報頭中 32bit 字的數目,它實際上指明數據從哪裏開始
      需要這個值是因爲任選字段的長度是可變的。這個字段佔 4bit ,因此 TCP 最多有 60 字節的首部。然而,沒有任選字段,正常的長度是 20 字節。

  6. 保留位( 6 位):保留給將來使用,目前必須置爲 0 。

  7. 控制位( control flags , 6 位):在 TCP 報頭中有 6 個標誌比特,它們中的多個可同時被設
    置爲 1 。依次爲:
      (1)URG :爲 1 表示緊急指針有效,爲 0 則忽略緊急指針值。
      (2)ACK :爲 1 表示確認號有效,爲 0 表示報文中不包含確認信息,忽略確認號字段。
      (3)PSH :爲 1 表示是帶有 PUSH 標誌的數據,指示接收方應該儘快將這個報文段交給應用層而不用等待緩衝區裝滿。
      (4)RST :用於復位由於主機崩潰或其他原因而出現錯誤的連接。它還可以用於拒絕非法的報文段和拒絕連接請求。一般情況下,如果收到一個 RST 爲 1 的報文,那麼一定發生了某些問題。
      (5)SYN :同步序號,爲 1 表示連接請求,用於建立連接和使順序號同步( synchronize )。
      (6)FIN :用於釋放連接,爲 1 表示發送方已經沒有數據發送了,即關閉本方數據流。

  8. 窗口大小( 16 位):數據字節數,表示從確認號開始,本報文的源方可以接收的字節數,即源方接收窗口大小。窗口大小是一個 16bit 字段,因而窗口大小最大爲 65535 字節。

  9. 校驗和( 16 位):此校驗和是對整個的 TCP 報文段,包括 TCP 頭部和 TCP 數據,以 16 位字進行計算所得。這是一個強制性的字段,一定是由發送端計算和存儲,並由接收端進行驗證

  10. 緊急指針( 16 位):只有當 URG 標誌置 1 時緊急指針纔有效。TCP 的緊急方式是發送端向另一端發送緊急數據的一種方式。

  11. 選項:最常見的可選字段是最長報文大小,又稱爲 MSS(Maximum Segment Size) 。
      每個連接方通常都在通信的第一個報文段(爲建立連接而設置 SYN 標誌的那個段)中指明這個選項,它指明本端所能接收的最大長度的報文段
      選項長度不一定是 32 位字的整數倍,所以要加填充位,使得報頭長度成爲整字數。

  12. 數據: TCP 報文段中的數據部分是可選的。在一個連接建立和一個連接終止時,雙方交換的報文段僅有 TCP 首部。如果一方沒有數據要發送,也使用沒有任何數據的首部來確認收到的數據。在處理超時的許多情況中,也會發送不帶任何數據的報文段。
    在這裏插入圖片描述

二、三次握手

1、圖解三次握手

簡單圖:
在這裏插入圖片描述
在這裏插入圖片描述
完整圖:
在這裏插入圖片描述

2、概述三次握手

第一次握手:主機 A 發送位碼爲 syn=1,隨機產生 seq number=1234567 的數據包到服務器,主機 B由 SYN=1 知道,A 要求建立聯機;

第二次握手:主機 B 收到請求後要確認聯機 信息,向 A 發 送 ack number=( 主機 A 的seq+1),syn=1,ack=1,隨機產生 seq=7654321 的包

第三次握手:主機 A 收到後檢查 ack number 是否正確,即第一次發送的 seq number+1,以及位碼ack 是否爲 1,若正確,主機 A 會再發送 ack number=(主機 B 的 seq+1),ack=1,主機 B 收到後確認seq 值與 ack=1 則連接建立成功。

三、四次揮手

1、爲什麼要四次揮手

任何⼀⽅都可以在數據傳送結束後發出連接釋放的通知,待對⽅確認後進⼊半關閉狀態。當另⼀⽅也沒有數據再發送的時候,則發出連接釋放通知,對⽅確認後就完全關閉了TCP連接。

舉個例⼦:A 和 B 打電話,通話即將結束後,A 說「我沒啥要說的了」,B回答「我知道了」,但是 B 可能還會有要說的話,A 不能要求 B 跟着⾃⼰的節奏結束通話,於是 B 可能⼜巴拉巴拉說了⼀通,最後B 說「我說完了」,A 回答「知道了」,這樣通話纔算結束。

TCP 建立連接要進行三次握手,而斷開連接要進行四次。這是由於 TCP 的半關閉造成的
因爲 TCP 連接是全雙工的(即數據可在兩個方向上同時傳遞);所以進行關閉時每個方向上都要單獨進行關閉。這個單方向的關閉就叫半關閉。
當一方完成它的數據發送任務,就發送一個 FIN 來向另一方通告將要終止這個方向的連接。

  1) 關閉客戶端到服務器的連接:首先客戶端 A 發送一個 FIN,用來關閉客戶到服務器的數據傳送,然後等待服務器的確認。其中終止標誌位 FIN=1,序列號 seq=u

  2) 服務器收到這個 FIN,它發回一個 ACK,確認號 ack 爲收到的序號加 1。

  3) 關閉服務器到客戶端的連接:也是發送一個 FIN 給客戶端。

  4) 客戶段收到 FIN 後,併發回一個 ACK 報文確認,並將確認序號 seq 設置爲收到序號加 1。
首先進行關閉的一方將執行主動關閉,而另一方執行被動關閉。

2、圖解四次揮手

簡單圖:
在這裏插入圖片描述
詳細圖:
在這裏插入圖片描述

主機 A 發送 FIN 後,進入終止等待狀態, 服務器 B 收到主機 A 連接釋放報文段後,就立即
給主機 A 發送確認,然後服務器 B 就進入 close-wait 狀態,此時 TCP 服務器進程就通知高
層應用進程,因而從 A 到 B 的連接就釋放了。此時是「半關閉」狀態。即 A 不可以發送給B,但是 B 可以發送給 A。
此時,若 B 沒有數據報要發送給 A 了,其應用進程就通知 TCP 釋放連接,然後發送給 A 連接釋放報文段,並等待確認。A 發送確認後,進入 time-wait,注意,此時 TCP 連接還沒有釋放掉,然後經過時間等待計時器設置的 2MSL 後,A 才進入到close 狀態。

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

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