輕鬆理解tcp的三次握手、四次揮手
介紹:tcp是面向連線的協議,運輸連線是用來傳送tcp報文的,所以每次連線都有三個過程:建立連線、資料傳送、連線釋放。
tcp連線建立過程中要解決一下三個問題:
(1)要使每一方知道對方的存在
(2)要允許雙方協商一些引數(如最大視窗值、是否使用視窗擴大選項等)
(3)能夠對運輸實體資源(如快取大小、連線表中的專案)進行分配
1.tcp的連線建立(三次握手)
先上圖:
(1)最初客戶端A和伺服器端B都處於CLOSED(關閉)狀態,客戶端A開始向伺服器B發出連線請求,客戶端主動開啟連線,伺服器B被動開啟連線,進入LESTEN(收聽)狀態。
(2)A的tcp客戶程序首先建立傳輸控制塊(TCB),然後向伺服器B傳送連線請求報文段,這時首部同部位SYN=1,選擇一個初始序號seq=x,規定該報文段不攜帶資料,但要消耗掉一個序號,此時客戶端進入SYN-SENT(同步已傳送)狀態。(一次握手
(3)伺服器B收到連線請求報文段,同意建立連線,並向客戶端A傳送確認。在確認報文段中把SYN=1,ACK=1,確認號ack=x+1,同時也為自己選擇一個初始序列號seq=y,這個報文段也不攜帶資料,仍要消耗一個序號,這時伺服器進入SYN-RECD(同步收到)狀態。(二次握手)
(4)客戶端收到伺服器B的確認後,還得向B確認,確認報文段的ACK=1,確認號ack=y+1,規定ACK報文段可以攜帶資料,如果不攜帶則不消耗序號。這時tcp連線建立,客戶端A進入ESTABLISHED(已建立連線)狀態。當伺服器B收到客戶端A的確認後,也進入ESTABLISHED狀態。(三次握手)
注意:為什麼客戶端A最後還要傳送一次確認呢?
----主要是為了防止已失效的連線請求報文段(一次握手的連線請求)突然又傳送到了伺服器B,因而產生錯誤。
----假如沒有第三次握手的確認,客戶端A傳送的連線請求由於網路延遲滯留了,於是A就再次重傳一次連線請求,這次連線成功,並且順利傳輸資訊後就斷開連線了,但這之後客戶端A第一次連線請求由於網路變通暢到達了伺服器B,B就答應連線,然後B就開始等待客戶端A傳送資訊,但是這是A之前發的請求,並且也互動完成了,現在A沒有請求連線,但伺服器B不知道,所以一直等待A發來資料。這樣B的許多資源就白白浪費了。
----採用三次握手了,客戶端A不會向伺服器B發出確認,B沒收到確認,就知道了A並沒有請求建立連線。
2.tcp的連線釋放(四次揮手)
還是先上圖:
(1)資料傳輸結束後,通訊的雙方都可以釋放連線。現在客戶端A和伺服器B都處於ESTABLISHED狀態。A的應用程序先向其tcp發出連線釋放報文段,並停止傳送資料,主動關閉tcp連線。A把連線釋放報文段首部的終止控制位FIN=1,序號seq=u,等於前面已傳過來的資料的最後一個位元組的序號加1。FIN報文段即使不攜帶資料,也消耗一個序號。此時A進入FIN-WAIT-1(終止等待1)狀態,等待B的確認。(一次揮手)
(2)伺服器B收到連線釋放報文段後即發出確認,確認號ack=u+1,seq=v,ack=u+1,B進入CLOSE-WAIT(關閉等待)狀態。tcp伺服器程序通知上面應用層程序,A到B的連線已經釋放了。此時tcp處於半關閉狀態。A沒有資料傳輸了,但要是B有資料傳送,A還是要接收的。(二次揮手
(3)A收到B的確認後,進入FIN-WAIT-2(終止等待2)狀態,等待B發出連線釋放報文段。B沒有資料傳送了,通知應用程序釋放連線,B傳送到連線釋放報文段FIN=1,ACK=1,seq=w,ack=u+1。此時B進入LAST-ACK(最後確認)狀態,等待A確認。(三次揮手)
(4)A收到B的連線釋放報文段後,必須對此發出確認。且ACK=1,ack=w+1,seq=u+1,,然後進入到TIME-WAIT(時間等待)狀態。此時tcp連線還沒有釋放。必須經過時間等待計時器設定的2MSL(Maxinum Segment Lifetime 最長報文段壽命)後,才進入CLOSED狀態。(四次揮手)
注:為什麼A在TIME-WAIT狀態必須等待2MSL的時間?有兩個理由
第一,保證A最後傳送的確認報文段傳送給B,這個ACK報文段可能會丟失,B就會超時重傳FIN+ACK報文段,A就再一次確認。2MSL後B沒有反應,就都進入CLOSED狀態,如果A不等就釋放連線,B可能沒收到確認,就進入不了CLOSED狀態。其實這個時間應該大於2MSL,因為A、B確認等操作可能會花一部分時間。
第二,防止失效的請求報文段出現在本次連線中,經過2MSL,可以使本連線持續的時間內所產生的所有報文段都從網路中消失。這樣可以使下次新的連線中不會出現這種舊的連線請求報文段。
最後我們注意到,B結束tcp連線的時間要比A早一些(可能是一個MSL)。