TCP 位於傳輸層,提供可靠的字節流服務。php
可靠的字節流服務:TCP 協議爲了傳輸方便,將大塊數據分割成以
報文段(segment)
爲單位的數據包進行管理,並可以把這些數據準確可靠的傳遞給對方。
下面是一張 TCP 報文格式的圖片:html
其中,幾個比較重要的字段以下:緩存
每一個 TCP 報文內都有序號和確認號,結合重傳機制保障數據傳輸的可靠性服務器
序號+1
,保證每發送不一樣的數據包,數據包的序號都是不一樣的網絡
seq+1
,之前的字節已經收到過了,ACK標誌位被設置爲1的時候,纔會發送ack確認號。TCP 報文共有6個標誌位,每一個佔1位,共6位,每一位的值只有0和1spa
TCP 鏈接的創建採用客戶-服務器模式,主動發起鏈接創建的應用進程叫作客戶,被動等待鏈接創建的應用進程叫作服務器,如下是創建 TCP 鏈接的過程:.net
客戶端向服務端發送請求鏈接
報文,將報文同步標誌位 SYN 的值設置爲1
,表示要建立鏈接,等待服務器確認,並進入SYN_SENT
狀態。(報文首部:SYN=1, 初始序號 seq=x(x爲隨機生成數值))
3d
服務端接收到客戶端的請求,回覆給客戶端確認報文,將報文確認標誌位 ACK 的值設置爲1
,告訴客戶端已收到它的請求,贊成建立鏈接,並進入SYN_RECV
狀態。(ACK=1,確認號 ack=x+1,SYN=1,初始序號 seq=y)
指針
客戶端接收到服務端的確認報文以後,爲了防止意外,再次向服務端發出確認報文,將報文ACK 的值設置爲1
,當服務端收到客戶端發來的確認報文以後,TCP 鏈接創建,客戶端和服務端都進入ESTABLISHED
狀態,完成三次握手,之後就能夠開森的傳遞數據了。(報文首部:ACK=1, 確認號 ack=y+1, 序號 seq=x+1(服務端傳過來的ack的值)
code
因爲 TCP 鏈接是雙工
的,所以每一個方向都必須單獨進行關閉。當一方完成它的數據發送任務後就能夠發送一個FIN
終止標誌位來終止這個方向上的鏈接,收到一個FIN
就意味着這一方向上沒有數據流動
。一個 TCP 鏈接在收到一個 FIN 後仍能發送數據,首先進行關閉的一方將執行主動關閉
,而另外一方執行被動關閉
。
客戶端主動向服務端發出斷開 TCP 鏈接
的請求報文,將報文終止標誌位 FIN 設置爲1
,表示要釋放 TCP 鏈接,並進入等待結束鏈接狀態FIN_WAIT-1
。(報文首部:FIN=1,序號 seq=u(u爲隨機數))
服務端收到客戶端的釋放鏈接請求後,回覆確認報文給客戶端,將報文確認標誌位 ACK 設置爲1
,表示已收到客戶端請求,關閉服務端讀通道
並進入關閉等待狀態 CLOSE-WAIT
。(報文首部:ACK=1,確認號 ack=u+1(收到的序號+1),序號 seq=v(v爲隨機數))
客戶端收到確認報文後,會關閉客戶端寫通道
,此時客戶端仍能經過讀通道讀取服務端的數據,服務器仍能經過寫通道寫數據。
服務端發送斷開 TCP 鏈接
的請求報文,將報文終止標誌位 FIN 設置爲1
。表示服務端數據已發送完畢,要釋放鏈接,不會再發送任何數據了。(報文首部:FIN=1,ACK=1,確認號 ack=u+1(收到的序號+1),序號 seq=w(w爲隨機數))
客戶端收到服務端的斷開鏈接請求後,回覆確認報文,將報文確認標誌位 ACK 設置爲1
,關閉客戶端讀通道
,服務端收到客戶端的確認報文
後,關閉服務端讀通道
。雙方讀寫通道所有關閉,完成四次揮手。(報文首部:ACK=1,確認號 ack=w+1(收到的序號+1),序號 seq=u+1(服務端傳過來的ack的值))
爲了防止已失效的鏈接請求報文段忽然又傳送到了服務端,於是產生錯誤。
在結束鏈接的過程當中,爲何在收到服務器端的鏈接釋放報文段以後,客戶端還要繼續等待2MSL以後才真正關閉TCP鏈接呢?
這裏有兩個緣由:
第一個是:須要保證服務器端收到了客戶端的最後一條確認報文。假如這條報文丟失,服務器沒有接收到確認報文,就會對鏈接釋放報文進行超時重傳,而此時客戶端鏈接已關閉,沒法作出響應,就形成了服務器端不停重傳鏈接釋放報文,而沒法正常進入關閉狀態的情況。而等待2MSL,就能夠保證服務器端收到了最終確認;若服務器端沒有收到,那麼在2MSL以內客戶端必定會收到服務器端的重傳報文,此時客戶端就會重傳確認報文,並重置計時器。
第二個是:存在一種「已失效的鏈接請求報文段」,須要避免這種報文端出如今本鏈接中,形成異常。這種「已失效的鏈接請求報文段」是這麼造成的:假如客戶端發出了鏈接請求報文,然而服務器端沒有收到,因而客戶端進行超時重傳,再一次發送了鏈接請求報文,併成功創建鏈接。然而,第一次發送的鏈接請求報文並無丟失,只是在某個網絡結點中發生了長時間滯留,隨後,這個最初發送的報文段到達服務器端,會使得服務器端誤覺得客戶端發出了新的請求,形成異常。
🍃 資料1:史上最容易理解的:TCP三次握手,四次揮手
🍃 資料2:TCP三次握手原理