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
過程如下圖所示:
2. TCP斷開連線的四次揮手
第一次揮手:主機1(可以是客戶端,也可以是伺服器端),設定Sequence Number
和Acknowledgment 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時長的原因。