TCP連線的「三次握手」與「4次揮手」

2021-10-24 11:35:27 字數 3750 閱讀 7855

「三次握手」:所謂的三次握手即tcp連線的建立。這個連線必須是一方主動開啟,另一方被動開啟的。

以下為客戶端主動發起連線的**:

握手之前主動開啟連線的客戶端結束closed階段,被動開啟的伺服器端也結束closed階段,並進入listen階段。隨後開始「三次握手」:

(1)首先客戶端向伺服器端傳送一段tcp報文,其中:標記位為syn,表示「請求建立新連線」;序號為seq=x(x一般為1);隨後客戶端進入syn-sent階段。

(2)伺服器端接收到來自客戶端的tcp報文之後,結束listen階段。並返回一段tcp報文,其中:標誌位為syn和ack,表示「確認客戶端的報文seq序號有效,伺服器能正常接收客戶端傳送的資料,並同意建立新連線」(即告訴客戶端,伺服器收到了你的資料);序號為seq=y;確認號為ack=x+1,表示收到客戶端的序號seq並將其值加1作為自己確認號ack的值;隨後伺服器端進入syn-rcvd階段。

(3)客戶端接收到來自伺服器端的確認收到資料的tcp報文之後,明確了從客戶端到伺服器的資料傳輸是正常的,結束syn-sent階段。並返回最後一段tcp報文。其中:標誌位為ack,表示「確認收到伺服器端同意連線的訊號」(即告訴伺服器,我知道你收到我發的資料了);序號為seq=x+1,表示收到伺服器端的確認號ack,並將其值作為自己的序號值;確認號為ack=y+1,表示收到伺服器端序號seq,並將其值加1作為自己的確認號ack的值;隨後客戶端進入established階段。伺服器收到來自客戶端的「確認收到伺服器資料」的tcp報文之後,明確了從伺服器到客戶端的資料傳輸是正常的。結束syn-sent階段,進入established階段。

在客戶端與伺服器端傳輸的tcp報文中,雙方的確認號ack和序號seq的值,都是在彼此ack和seq值的基礎上進行計算的,這樣做保證了tcp報文傳輸的連貫性。一旦出現某一方發出的tcp報文丟失,便無法繼續"握手",以此確保了"三次握手"的順利完成。此後客戶端和伺服器端進行正常的資料傳輸。這就是「三次握手」的過程。

為什麼要進行「三次握手」:為了防止伺服器端開啟一些無用的連線增加伺服器開銷以及防止已失效的連線請求報文段突然又傳送到了服務端,因而產生錯誤。

「四次揮手」:所謂的四次揮手即tcp連線的釋放(解除)。連線的釋放必須是一方主動釋放,另一方被動釋放。

以下為客戶端主動發起釋放連線的**:

(1)首先客戶端想要釋放連線,向伺服器端傳送一段tcp報文,其中:標記位為fin,表示「請求釋放連線「;序號為seq=u;隨後客戶端進入fin-wait-1階段,即半關閉階段。並且停止在客戶端到伺服器端方向上傳送資料,但是客戶端仍然能接收從伺服器端傳輸過來的資料。注意:這裡不傳送的是正常連線時傳輸的資料(非確認報文),而不是一切資料,所以客戶端仍然能傳送ack確認報文。

(2)伺服器端接收到從客戶端發出的tcp報文之後,確認了客戶端想要釋放連線,隨後伺服器端結束established階段,進入close-wait階段(半關閉狀態)並返回一段tcp報文,其中:標記位為ack,表示「接收到客戶端傳送的釋放連線的請求」;序號為seq=v;確認號為ack=u+1,表示是在收到客戶端報文的基礎上,將其序號seq值加1作為本段報文確認號ack的值;隨後伺服器端開始準備釋放伺服器端到客戶端方向上的連線。客戶端收到從伺服器端發出的tcp報文之後,確認了伺服器收到了客戶端發出的釋放連線請求,隨後客戶端結束fin-wait-1階段,進入fin-wait-2階段前"兩次揮手"既讓伺服器端知道了客戶端想要釋放連線,也讓客戶端知道了伺服器端了解了自己想要釋放連線的請求。於是,可以確認關閉客戶端到伺服器端方向上的連線了

(3)伺服器端自從發出ack確認報文之後,經過closed-wait階段,做好了釋放伺服器端到客戶端方向上的連線準備,再次向客戶端發出一段tcp報文,其中:標記位為fin,ack,表示「已經準備好釋放連線了」。注意:這裡的ack並不是確認收到伺服器端報文的確認報文。序號為seq=w;確認號為ack=u+1;表示是在收到客戶端報文的基礎上,將其序號seq值加1作為本段報文確認號ack的值。隨後伺服器端結束close-wait階段,進入last-ack階段。並且停止在伺服器端到客戶端的方向上傳送資料,但是伺服器端仍然能夠接收從客戶端傳輸過來的資料。

(4)客戶端收到從伺服器端發出的tcp報文,確認了伺服器端已做好釋放連線的準備,結束fin-wait-2階段,進入time-wait階段,並向伺服器端傳送一段報文,其中:標記位為ack,表示「接收到伺服器準備好釋放連線的訊號」。序號為seq=u+1;表示是在收到了伺服器端報文的基礎上,將其確認號ack值作為本段報文序號的值。確認號為ack=w+1;表示是在收到了伺服器端報文的基礎上,將其序號seq值作為本段報文確認號的值。隨後客戶端開始在time-wait階段等待2msl為什麼要客戶端要等待2msl呢?見後文。伺服器端收到從客戶端發出的tcp報文之後結束last-ack階段,進入closed階段。由此正式確認關閉伺服器端到客戶端方向上的連線。客戶端等待完2msl之後,結束time-wait階段,進入closed階段,由此完成「四次揮手」。

後「兩次揮手」既讓客戶端知道了伺服器端準備好釋放連線了,也讓伺服器端知道了客戶端了解了自己準備好釋放連線了。於是,可以確認關閉伺服器端到客戶端方向上的連線了,由此完成「四次揮手」。

與「三次揮手」一樣,在客戶端與伺服器端傳輸的tcp報文中,雙方的確認號ack和序號seq的值,都是在彼此ack和seq值的基礎上進行計算的,這樣做保證了tcp報文傳輸的連貫性,一旦出現某一方發出的tcp報文丟失,便無法繼續"揮手",以此確保了"四次揮手"的順利完成。

為什麼「握手」是三次,「揮手」卻要四次?

tcp建立連線時之所以只需要"三次握手",是因為在第二次"握手"過程中,伺服器端傳送給客戶端的tcp報文是以syn與ack作為標誌位的。syn是請求連線標誌,表示伺服器端同意建立連線;ack是確認報文,表示告訴客戶端,伺服器端收到了它的請求報文。即syn建立連線報文與ack確認接收報文是在同一次"握手"當中傳輸的,所以"三次握手"不多也不少,正好讓雙方明確彼此資訊互通。

tcp釋放連線時之所以需要「四次揮手」,是因為fin釋放連線報文與ack確認接收報文是分別由第二次和第三次"握手"傳輸的。為何建立連線時一起傳輸,釋放連線時卻要分開傳輸?建立連線時,被動方伺服器端結束closed階段進入「握手」階段並不需要任何準備,可以直接返回syn和ack報文,開始建立連線。釋放連線時,被動方伺服器,突然收到主動方客戶端釋放連線的請求時並不能立即釋放連線,因為還有必要的資料需要處理,所以伺服器先返回ack確認收到報文,經過close-wait階段準備好釋放連線之後,才能返回fin釋放連線報文。

所以是「三次握手」,「四次揮手」。

為什麼客戶端在time-wait階段要等2msl?

為的是確認伺服器端是否收到客戶端發出的ack確認報文當客戶端發出最後的ack確認報文時,並不能確定伺服器端能夠收到該段報文。所以客戶端在傳送完ack確認報文之後,會設定乙個時長為2msl的計時器。msl指的是maximum segment lifetime:一段tcp報文在傳輸過程中的最大生命週期。2msl即是伺服器端發出為fin報文和客戶端發出的ack確認報文所能保持有效的最大時長。伺服器端在1msl內沒有收到客戶端發出的ack確認報文,就會再次向客戶端發出fin報文;如果客戶端在2msl內,再次收到了來自伺服器端的fin報文,說明伺服器端由於各種原因沒有接收到客戶端發出的ack確認報文。客戶端再次向伺服器端發出ack確認報文,計時器重置,重新開始2msl的計時;否則客戶端在2msl內沒有再次收到來自伺服器端的fin報文,說明伺服器端正常接收了ack確認報文,客戶端可以進入closed階段,完成「四次揮手」。

所以,客戶端要經歷時長為2sml的time-wait階段;這也是為什麼客戶端比伺服器端晚進入closed階段的原因

tcp的4次揮手 三次握手

1.tcp短連線 模擬一種tcp短連線的情況 1.client 向 server 發起連線請求 2.server 接到請求,雙 建 連線 3.client 向 server 傳送訊息 4.server 回應 client 5.一次讀寫完成,此時雙方任何乙個都可以發起 close 操作 在步驟5中,一...

tcp的三次握手和4次揮手

第一次握手 host1傳送乙個tcp標誌位syn 1 ack 0的資料報給host2,並隨機會產生乙個sequence number 3233.當host2接收到這個資料後,host2由syn 1可知客戶端是想要建立連線 第二次握手 host2要對客戶端的聯機請求進行確認,向host1傳送應答號ac...

TCP協議的三次握手 4次揮手

tcp的連線建立是乙個三次握手過程,目的是為了通訊雙方確認開始序號,以便後續通訊的有序進行。主要步驟如下 連線開始時,連線建立方 client 傳送syn包,幷包含了自己的初始序號a 連線接受方 server 收到syn包以後會回覆乙個syn ack包,其中包含了對上乙個a包的回應資訊ack,回應的...