TCP三次握手和四次揮手

2022-09-03 13:33:12 字數 2865 閱讀 7290

tcp協議是面向連線的協議,在建立連線的時候需要經過三次握手;在關閉連線的時候需要四次揮手。

圖示[1]

客戶端向服務端傳送乙個特殊的tcp報文段,不包含應用層資料但syn位元位被設定為1。因此這個報文段也稱syn報文段

同時客戶端會隨機選擇乙個初始的序列號放在該報文段中,一併傳送給服務端。

經過該階段,伺服器確認了客戶端的傳送正常、自己的接收正常。

伺服器收到syn報文段後,會為該tcp連線分配tcp快取和變數,並向客戶端傳送允許連線的報文段。

該報文段被稱為synack報文段。不包含應用層資料,但有以下重要資訊:

經過該階段,客戶端確認了自己的傳送和接收正常、對方的傳送和接收正常。

客戶端收到synack報文段後,客戶端為該連線分配快取和變數,同時向伺服器傳送另乙個報文段。這個報文段對伺服器的允許連線報文段進行了確認,它具有以下特點:

經過該階段,伺服器確認了客戶端的接收正常、自己的傳送正常。

為什麼需要進行三次握手,而不是兩次?

三次握手的目的是建立可靠的通訊通道,而由上述過程可以看出,經過三次握手,伺服器和客戶端都確認了雙方的傳送和接收正常。這三次握手缺一不可。

為什麼要傳回syn

接收端傳回傳送端的syn目的是為了告訴傳送端我確認接收到的確實是你傳送的報文段,而不是其他客戶端傳送的報文段。

tcp連線的建立通常都由客戶端發起,而參與一條tcp連線的兩個程序中的任意一方都能終止該連線。我們假設client向server發起了tcp連線終止的命令。

圖示[^pic2]:

client傳送乙個特殊的報文段,將fin置1,並指定了序列號。

此時client進入fin_wait_1狀態,傳送連線釋放的報文段,並停止再傳送資料,等待server端的確認。

server傳送ack給client,表示接受到了這個報文段,同時上層應用會得知對方發起了關閉連線操作,通常應用程式會對此作出自己的關閉操作。

此時,server端處於close_wait階段,即關閉等待。此時的tcp連線處於半關閉狀態,客戶端到server端的連線釋放。等到client端接收到server的ack之後,進入fin_wait_2狀態。

如果server端也想斷開連線了,那麼server像第一次揮手一樣傳送fin給client,並且指定乙個序列號。

此時server處於last_ack狀態,即最後確認狀態,等待client端的確認。

client傳送ack,確認收到了server的fin報文段

此時client處於time_wait狀態,等待一段時間之後才進入close狀態,目的是確保server端收到了自己的ack。

server端收到了ack之後就進入了close狀態。

2msl等待狀態:

time_wait也稱為2msl等待狀態。每個具體tcp實現必須選擇乙個報文段最大生存時間msl(maximum segment lifetime),它是任何報文被丟棄前再網路內的最長時間。這個時間是有限的,因為tcp報文以ip資料報在網路內傳輸,而ip資料報則有限制其生存時間的ttl欄位。

對乙個具體實現所給定的msl值,處理的原則是:當tcp執行乙個主動關閉,並發回最後乙個ack,該連線必須在time_wait狀態停留的時間為2倍的msl。這樣可讓tcp再次傳送最後的ack以防這個ack丟失(另一端超時並重發最後的fin)。

這種2msl等待的另乙個結果是這個tcp連線在2msl等待期間,定義這個連線的socket(客戶的ip位址和埠號,伺服器的ip位址和埠號)不能再被使用。這個連線只能在2msl結束後才能再被使用

為什麼需要揮手四次?

和建立連線的三次揮手不同,建立連線時,一旦server端收到了syn報文之後,就可以立即回覆synack報文。

而關閉連線的過程中,當server端收到fin報文的時候,很可能不會立刻關閉socket,所以只能先回覆乙個ack報文,告訴對方已經收到了fin,而只有等server端的所有報文都傳送完了,才能傳送fin報文。

四次揮手釋放連線時,為什麼要等待2msl?

保證客戶端傳送的最後乙個ack報文段能夠到達服務端。

這個ack報文段有可能丟失,使得處於last-ack狀態的b收不到對已傳送的fin+ack報文段的確認,服務端超時重傳fin+ack報文段,而客戶端能在2msl時間內收到這個重傳的fin+ack報文段,接著客戶端重傳一次確認,重新啟動2msl計時器,最後客戶端和服務端都進入到closed狀態,若客戶端在time-wait狀態不等待一段時間,而是傳送完ack報文段後立即釋放連線,則無法收到服務端重傳的fin+ack報文段,所以不會再傳送一次確認報文段,則服務端無法正常進入到closed狀態。

防止「已失效的連線請求報文段」出現在本連線中。

客戶端在傳送完最後乙個ack報文段後,再經過2msl,就可以使本連線持續的時間內所產生的所有報文段都從網路中消失,使下乙個新的連線中不會出現這種舊的連線請求報文段。

來自知乎專欄:

↩︎參考掘金「猿人谷」的文章:

↩︎

tcp 四次揮手 TCP的三次握手和四次揮手

三次握手 第一次握手 客戶端傳送syn包 syn x 到伺服器,並進入syn send狀態,等待伺服器確認 第二次握手 伺服器收到syn包,必須確認客戶的syn ack x 1 同時自己也傳送乙個syn包 syn y 即syn ack包,此時伺服器進入syn recv狀態 第三次握手 客戶端收到伺服...

TCP三次握手和四次揮手

一 tcp三次握手 three way handshake 1 tcp三次握手的作用 三次握手的目的是連線伺服器指定埠,建立tcp連線,並同步連線雙方的序列號和確認號並交換 tcp 視窗大小資訊。在socket程式設計中,客戶端執行connect 時,將觸發三次握手。2 tcp三次握手過程 第一步 ...

TCP三次握手和四次揮手

三次握手 四次揮手 需四次揮手原因 由於tcp的半關閉特性,tcp連線時雙全工 即資料在兩個方向上能同時傳遞 因此,每個方向必須單獨的進行關閉。這個原則就是 當一方完成它的資料傳送任務後就能傳送乙個fin來終止這個方向上的連線。當一端收到乙個fin後,它必須通知應用層另一端已經終止了那個方向的資料傳...