1. 程式人生 > >TCP三次握手(建立連線)與四次揮手(釋放連線)詳解

TCP三次握手(建立連線)與四次揮手(釋放連線)詳解

這裡寫圖片描述

上圖畫出了TCP的建立連線的過程。假定主機A執行的是TCP客戶程式,而B執行TCP服務程式。最初兩端的TCP程序都處於 CLOSED(關閉)狀態。圖中在主機下面的方框分別是TCP程序所處的狀態。請注意,A主動開啟連線,而B被動開啟連線。

B的TCP伺服器程序先建立傳輸控制塊TCB(Transmission Control Block),準備接受客戶程序的連線請求。然後伺服器程序就處於LISTEN(監聽)狀態,等待客戶的連線請求。如有,即做出響應。

A的TCP客戶程序也是首先建立傳輸控制塊TCB,然後向B發出連線請求報文段,這時首部中的同步位SYN = 1,同時選擇一個初始序號seq = x。TCP規定,SYN報文段(即SYN = 1的報文段)不能攜帶資料,但要消耗掉一個序號。

這時,TCP客戶程序進入SYN-SENT(同步已傳送)狀態。

B收到連線請求報文後,如果同意建立連線,則向A傳送確認。在確認報文段中應把SYN位和ACK位都置1,確認號ack = x + 1,同時也為自己選擇一個初始序號seq = y。請注意,這個報文段也不能攜帶資料,但同樣要消耗掉一個序號。這時TCP伺服器程序進入SYN-RCVD(同步收到)狀態。

TCP客戶程序收到B的確認後,還要向B給出確認。確認報文段的ACK置1,確認號ack = y + 1,而自己的序號seq = x + 1。TCP的標準規定,ACK報文段可以攜帶資料。但如果不攜帶資料則不消耗序號,在這種情況下,下一個資料報文段的序號仍是seq = x + 1。這時,TCP連線已經建立,A進入ESTABLISHED(已建立連線)狀態。

當B收到A的確認後,也進入ESTABLISHED狀態。

上面給出的連線建立過程叫做三次握手(three-way handshake)

為什麼A還要傳送一次確認呢?這主要是為了防止已失效的連線請求報文突然又送到了B,因而產生錯誤。

下面再看看TCP四次揮手(釋放連線)

這裡寫圖片描述

現在A和B都處於ESTABLISHED狀態。A的應用程序先向其TCP發出連線釋放報文段,並停止再發送資料,主動關閉TCP連線。

A把連線釋放報文段首部的終止控制位置1,其序號seq = u,u等於前面已傳送過的資料的最後一個位元組加上1。這時A進入FIN-WAIT-1(終止等待1)狀態,等待B的確認。請注意,FIN報文段即使不攜帶資料,他也要消耗掉一個序號。

B收到連線釋放報文段後即傳送出確認,確認號ack = u + 1,而這個報文段自己的序號是seq = v,v等於B前面已傳送過的資料的最後一個位元組的序號加1.然後B進入CLOSE-WAIT(關閉等待)狀態。TCP伺服器程序這時應通知高層應用程序,因而從A到B這個方向的連線就釋放了,這時的TCP連線處於半關閉(half-close)狀態,即A已經沒有時間要傳送了,但B若傳送資料,A仍要接收。也就是說,從B到A這個方向的連線並未關閉,這個狀態可能會持續一些時間。

A收到來自B的確認後,就進入FIN-WAIT-2(終止等待2)狀態,等待B發出的連線釋放報文段。

若B已經沒有要向A傳送的資料,其應用程序就通知TCP釋放連線。這時B發出的連線釋放報文段必須使FIN = 1。現假定B的序號為w(在半關閉狀態B可能又傳送了一些資料)。B還必須重複上次已經發送過的確認號ack = u + 1。這時B就進入了LAST-ACK(最後確認)狀態,等待A的確認。

A在收到B的連線釋放確認後們必須對此發出確認。在確認報文段中把ACK置1,確認號ack = w + 1,而自己的序號seq = u + 1(根據TCP標準,前面傳送過的FIN報文段要消耗一個序號)。然後進入到TIME-WAIT(時間等待)狀態。請注意,現在TCP連線還沒有釋放掉,必須經過時間等待計時器(TIME-WAIT timer)設定的時間2MSL後,A才進入CLOSED狀態。MSL叫做最長報文段壽命(Maximum Segment Lifetime),建議時間為2分鐘,也可以使用更小的值。因此,從A進入到TIME-WAIT狀態後,要經過4分鐘才能進入到CLOSED狀態,才能開始建立下一個新的連線。當A撤銷相應的傳輸控制塊TCB後,就結束了這次的TCP連線。

B只要收到了A發出的確認,就進入CLOSED狀態。同樣,B在撤銷相應的傳輸控制塊TCB後,就結束了這次的TCP連線。我們注意到,B結束TCP連線的時間要比A早一些。

上述了連線釋放過程就是四次揮手

為什麼A在TIME-WAIT狀態必須等待2MSL的時間呢?

  1. 為了保證A傳送了最後一個ACK報文段能夠到達B。
  2. 防止已經失效的連線請求報文段出現在本連線中。

除了時間等待計時器外,TCP還設有一個保活計時器(keepalive timer)來防止客戶端的主機出現故障而導致的資源浪費。