【三次握手】
第一次握手:Client端會發送一個SYN标記為1的包,并随機取了一個随機數SEQ©=x為自己的初始序列号,發送完後進入SYN-SEND狀态。
第二次握手:Server端收到了SYN=1的标記,知道了Client端想要和自己建立連接配接,此時進入LISTEN狀态。于是發送包含一個确認标記ACK(ACK=SEQ©+1),一個建立連接配接标記SYN=1,并且随機産生自己的序列書SEQ(s)=y的包,發送完後進入SYN-RECV狀态。
第三次握手:Client端收到Server端發來的包之後,檢查ACK的值是否等于SEQ©+1以及SYN是否為1,确認無誤後,再發送包含一個ACK=SEQ(s)+1,一個SEQ=z,此時雙方進入ESTABLISHED狀态,TCP連接配接建立。
【四次揮手】
四次揮手有兩種情況,這裡我選取用戶端主動發起關閉請求來講解。
第一次揮手:Client端主動斷開連接配接,并發送一個包含FIN=1,SEQ=u(等于前面已經傳送過來的資料的最後一個位元組的序号加1,因為TCP協定規定FIN封包段即使不攜帶資料,也要消耗一個序号)的請求斷開封包,發送完後進入FIN-WAIT-1狀态;
第二次揮手:Server端收到了斷開請求封包,便發送一個包含ACK=u+1,SEQ=z的确認封包,發送完後進入CLOSE-WAIT狀态。Client端收到Server端的确認封包後,Client端進入FIN-WAIT-2狀态,繼續接受Server端發送的最後的封包;
第三次揮手:等所有的資料傳送完畢後,Server端發送一個包含FIN=1,SEQ=w,ACK=u+1的連接配接斷開封包,此時Server端進入LAST-ACK狀态。
第四次揮手:Client端收到斷開連接配接封包後,必須要發送一個包含ACK=w+1,SEQ=u+1的确認斷開封包,此時Client端進入TIME-WAIT狀态,Server端進入CLOSED狀态,等待2MSL(最長封包壽命)時間後,Server端進入CLOSED狀态,雙方正式斷開連接配接。
1、為什麼連接配接的時候是三次握手,關閉的時候卻是四次握手?
因為當Server端收到Client端的SYN連接配接請求封包後,可以直接發送SYN+ACK封包。其中ACK封包是用來應答的,SYN封包是用來同步的。但是關閉連接配接時,當Server端收到FIN封包時,很可能并不會立即關閉SOCKET,是以隻能先回複一個ACK封包,告訴Client端,“你發的FIN封包我收到了”。隻有等到我Server端所有的封包都發送完了,我才能發送FIN封包,是以不能一起發送。故需要四步握手。
2、為什麼TIME_WAIT狀态需要經過2MSL(最大封包段生存時間)才能傳回到CLOSE狀态?
雖然按道理,四個封包都發送完畢,我們可以直接進入CLOSE狀态了,但是我們必須假象網絡是不可靠的,有可能最後一個ACK丢失。是以TIME_WAIT狀态就是用來重發可能丢失的ACK封包。在TIME_WAIT狀态中,如果TCP client端最後一次發送的ACK丢失了,它将重新發送。TIME_WAIT狀态中所需要的時間是依賴于實作方法的。典型的值為30秒、1分鐘和2分鐘。等待之後連接配接正式關閉,并且所有的資源(包括端口号)都被釋放。