1. 程式人生 > >TCP三次握手、四次握手

TCP三次握手、四次握手

如果 就是 三次 應用程序 產生 通知 的確 計時器 同時

 前言

  TCP用於應用程序之間的通信。當應用程序希望通過TCP與另一個應用程序通信時,它會發送一個通信請求。這個請求必須被送到一個確切的地址。在雙方“握手”之後,TCP將在兩個應用程序之間建立一個全雙工的通信 。這個全雙工的的通信將占用兩個計算機之間的通信線路,直到它被一方或雙方關閉為止 。

由於TCP提供的是一種面向連接的、可靠的字節流服務。

  所以本文講解連接建立時的“三次握手”、連接釋放時的“四次握手”。

一、TCP的運輸連接管理

1、TCP的連接建立(三次握手)

技術分享圖片

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

  B的TCP服務器進程先創建傳輸控制塊TCB(存儲了每一個連接中的一些重要信息,如:TCP連接表,到發送和接收緩存的指針,到重傳隊列的指針,當前的發送和接收序號,等等),準備接受客戶進程的連接請求。然後服務器進程就處於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狀態。

  上面給出的連接建立過程叫做三次握手。

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

  所謂“已失效的連接請求報文段”是這樣產生的。考慮一種正常情況。A發出連接請求,但因連接請求報文丟失而未收到確認。於是A再重傳一次連接請求。後來收到了確認,建立了連接。數據傳輸完畢後,就釋放了連接。A共發送了兩個連接請求報文段,其中第一個丟失,第二個到達了B。沒有“已失效的連接請求報文段”。

  現假定出現一種異常情況,即A發出的第一個連接請求報文段並沒有丟失,而是在某些網絡結點長時間滯留了,以致延誤到連接釋放以後的某個時間才到達B。本來這是一個早已失效的報文段。但B受到此失效的連接請求報文段後,就誤認為A又發出一次新的連接請求。於是就向A發出確認報文段,同意建立連接。假定不采用三次握手,那麽只要B發出確認,新的連接就建立了。

  由於現在A並沒有發出建立連接的請求,以你次不會理睬B的確認,也不會向B的確認發出確認。B由於收不到確認,就知道A並沒有要求建立連接。

2、TCP的連接釋放(四次握手)

  技術分享圖片

  數據傳輸結束後,通信的雙方都可釋放連接。現在A和B都處於ESTABLISHED狀態。A的應用進程先向其TCP發出連接釋放報文段,並停止再發送數據,主動關閉TCP連接。A把連接釋放報文段首部的終止控制位FIN置1,其序號seq=u,它等於前面已傳送過得數據的最後一個字節的序號加1。這時A進入FIN-WAIT-1(終止等待1)狀態,等待B的確認。請註意。TCP規定,FIN報文段即使不攜帶數據,它也消耗掉一個序號。

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

  A收到來自B的確認後,就進入GIN-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。然後進入到TIME-WAIT(時間等待)狀態。請註意,現在TCP連接還沒有釋放掉。必須經過時間等待計時器(TIME-WAIT timer)設置的時間2MSL後(原因為了使B按照正常步驟進入CLOSED、也為了出現已失效的連接請求報文段),A才進入到CLOSED狀態。時間MSL叫做最長報文段壽命,RFC793建議設為2分鐘。一次。從A進入到TIME-WAIT狀態後,要經過4分鐘才能進入到CLOSED狀態,才能建立下一個新的連接。當A撤銷相應的傳輸控制塊TCB後,就結束了這次的TCP連接。

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

  本文參考謝希仁編著的《計算機網絡》

TCP三次握手、四次握手