天天看點

16.2 三次握手、四次揮手;

用三次握手建立TCP連接配接

16.2 三次握手、四次揮手;

TCP連接配接的建立采用客戶伺服器方式。主動發起連接配接建立的應用程序叫做客戶,被動等待連接配接建立的應用程序叫做伺服器。

假設主機a運作的是tcp用戶端程式,b運作的是tcp伺服器端程式。最初兩端的tcp程序都處于closed狀态。

B的tcp伺服器程序先建立傳輸控制塊TCB,準備接受客戶程序的連接配接請求。然後伺服器程序就處于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連接配接已經建立,A進入ESTABLISHED(已連接配接狀态)。當B收到A的确認後,也進入ESTABLISHED狀态。以上便是三次握手的流程。

問題:

  1.為什麼不可以是兩次握手?為什麼A還要發送一次确認?

  答:主要是為了防止已失效的連接配接請求封包段突然又傳送到了B,因而産生錯誤。

  比如說這種異常情況:A發出的第一個連接配接請求封包段并沒有丢失,而是在某些網絡結點長時間滞留了,以緻延誤到連接配接釋放以後的某個時間才到達B。本來這是一個早已失效的封包段。但B收到此失效的連接配接請求封包段後,就誤以為是A又發出一次新的連接配接請求。于是就向A發出确認封包段,同意建立連接配接。假定不采用三次握手,那麼隻要B發出确認,新的連接配接就建立了。

  由于現在A并沒有發出建立連接配接的請求,是以不會理财B的确認,也不會向B發送資料。但B卻以為新的連接配接已經建立了,并一直等待A發來資料。B的許多資源就這樣被浪費。

采用三次握手的辦法可以防止上述現象的發生。例如在剛才的情況下,A不會向B的确認發出确認。B由于收不到确認,就知道A并沒有要求建立連接配接。

四次握手:TCP的連接配接釋放

16.2 三次握手、四次揮手;

TCP的連接配接釋放

資料傳輸結束後,通信的雙方都可釋放連接配接。現在A和B都處于ESTABLISHED狀态。A的應用程序先向其TCP發出連接配接釋放封包段,

并停止再發送資料,主動關閉TCP連接配接。

A把連接配接釋放封包段首部的終止控制位FIN置1,其序号seq=u,這時A進入FIN-WAIT-1(終止等待1)狀态,等待B的确認。

B收到連接配接釋放封包段後即發出确認,确認号是ack=u+1,這個封包段自己的序号是v,然後B就進入CLOSE-WAIT(關閉等待)狀态,

這時,如B發送資料,A仍要接收。

A收到來自B的确認後,就進入FIN-WAIT-2(終止等待2)狀态,等待B發出的連接配接釋放封包段。

若B已經沒有要向A發送的資料,其應用程序就通知TCP釋放連接配接。這時B發出的連接配接釋放封包段必須使FIN=1。B需要重複上次已發送過的确認号

ack=u+1。這時B就進入LAST-ACK(最後确認)狀态,等待A的确認。(假定此時B的序号為w)

A在收到B的連接配接釋放封包段後,必須對此發出确認,在确認封包段中把ACK置1,确認号ack=w+1,而自己的序号是seq=u+1(根據TCP标準,

前面發送過的FIN封包段要消耗一個序号)。然後進入到TIME-WAIT(時間等待狀态)。注意,現在TCP連接配接還沒有釋放掉。必須經過時間等待

計時器設定的時間2MSL後,A才進入到CLOSED狀态。時間MSL叫做最長封包段壽命。

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

為了保證A發送的最後一個ACK封包段能夠到達B。這個ACK封包段有可能丢失,如果丢失,B會逾時重傳FIN+ACK封包段。

B隻要收到了A發送的确認,就進入CLOSED狀态。

上述的TCP連接配接釋放過程是四次握手。

SYN:同步序列編号(Synchronize Sequence Numbers)。是TCP/IP建立連接配接時使用的握手信号。

seq和ack号存在于TCP封包段的首部中,seq是序号,ack是确認号,大小均為4位元組。

ACK表示響應

SYN表示建立連接配接,FIN表示關閉連接配接

問題:

  1.為什麼建立連接配接時是三次握手,而斷開時需要四次握手?

  答:因為當Server端收到Client端的SYN連接配接請求封包後,可以直接發送SYN+ACK封包。其中ACK封包是用來應答的,SYN封包是用來同步的。但是關閉連接配接時,當Server端收到FIN封包時,很可能并不會立即關閉SOCKET,是以隻能先回複一個ACK封包,告訴Client端,"你發的FIN封包我收到了"。隻有等到我Server端所有的封包都發送完了,我才能發送FIN封包,是以不能一起發送。故需要四步握手。