1. 程式人生 > >TCP的三次握手和四次揮手圖解

TCP的三次握手和四次揮手圖解

 1. TCP建立連線的三次握手

(1)第一次握手:Client將標誌位SYN置為1,隨機產生一個值seq=J,並將該資料包傳送給Server,Client進入SYN_SENT狀態,等待Server確認

(2)第二次握手:Server收到資料包後由標誌位SYN=1知道Client請求建立連線,Server將標誌位SYN和ACK都置為1,ack=J+1,隨機產生一個值seq=K,並將該資料包傳送給Client以確認連線請求,Server進入SYN_RCVD狀態。

(3)第三次握手:Client收到確認後,檢查ack是否為J+1,ACK是否為1,如果正確則將標誌位ACK置為1,ack=K+1,並將該資料包傳送給Server

,Server檢查ack是否為K+1,ACK是否為1,如果正確則連線建立成功,Client和Server進入ESTABLISHED狀態,完成三次握手,隨後Client與Server之間可以開始傳輸資料了。

過程如下圖所示:

 2. TCP斷開連線的四次揮手

第一次揮手:主機1(可以是客戶端,也可以是伺服器端),設定Sequence NumberAcknowledgment Number,向主機2傳送一個FIN報文段;此時,主機1進入FIN_WAIT_1狀態;這表示主機1沒有資料要傳送給主機2了;

第二次揮手:主機2收到了主機1傳送的FIN報文段,向主機1回一個ACK報文段,Acknowledgment Number

Sequence Number加1;主機1進入FIN_WAIT_2狀態;主機2告訴主機1,我也沒有資料要傳送了,可以進行關閉連線了;

第三次揮手:主機2向主機1傳送FIN報文段,請求關閉連線,同時主機2進入CLOSE_WAIT狀態;

第四次揮手:主機1收到主機2傳送的FIN報文段,向主機2傳送ACK報文段,然後主機1進入TIME_WAIT狀態;主機2收到主機1的ACK報文段以後,就關閉連線;此時,主機1等待2MSL後依然沒有收到回覆,則證明Server端已正常關閉,那好,主機1也可以關閉連線了。

三次握手、四次揮手完整圖:

問題

1.為什麼TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?

MSL是Maximum Segment Lifetime英文的縮寫,中文可以譯為“報文最大生存時間”,他是任何報文在網路上存在的最長時間,超過這個時間報文將被丟棄。2MSL 即是2倍的“報文最大最大生存時間“

雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網路是不可靠的,有可以最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。

2.client傳送完最後一個ack之後,進入time_wait狀態,但是他怎麼知道server有沒有收到這個ack呢?莫非sever也要等待一段時間,如果收到了這個ack就close,如果沒有收到就再發一個fin給client?這麼說server最後也有一個time_wait哦?

因為網路原因,主動關閉的一方傳送的這個ACK包很可能延遲,從而觸發被動連線一方重傳FIN包。極端情況下,這一去一回,就是兩倍的MSL時長。如果主動關閉的一方跳過TIME_WAIT直接進入CLOSED,或者在TIME_WAIT停留的時長不足兩倍的MSL,那麼當被動關閉的一方早先發出的延遲包到達後,就可能出現類似下面的問題:1.舊的TCP連線已經不存在了,系統此時只能返回RST包2.新的TCP連線被建立起來了,延遲包可能干擾新的連線,這就是為什麼time_wait需要等待2MSL時長的原因。