建立TCP需要三向交握才能建立,而中斷連線則需要四次握手。整個過程如所示:
先來看看如何建立串連的。
【更新於2017.01.04 】該部分內容配圖有誤,請大家見諒,正確的配圖如下,錯誤配圖也不刪了,大家可以比較下,對比理解效果更好。這麼久才來更新,抱歉!!
錯誤配圖如下:
首先Client端發送串連請求報文,Server段接受串連後回複ACK報文,並為這次串連分配資源。Client端接收到ACK報文後也向Server段發生ACK報文,並分配資源,這樣TCP串連就建立了。
那如何中斷連線呢?簡單的過程如下:
【注意】中斷串連端可以是Client端,也可以是Server端。
假設Client端發起中斷串連請求,也就是發送FIN報文。Server端接到FIN報文後,意思是說"我Client端沒有資料要發給你了",但是如果你還有資料沒有發送完成,則不必急著關閉Socket,可以繼續發送資料。所以你先發送ACK,"告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的訊息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。當Server端確定資料已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊資料發完了,準備好關閉串連了"。Client端收到FIN報文後,"就知道可以關閉串連了,但是他還是不相信網路,怕Server端不知道要關閉,所以發送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。“,Server端收到ACK後,"就知道可以中斷連線了"。Client端等待了2MSL後依然沒有收到回複,則證明Server端已正常關閉,那好,我Client端也可以關閉串連了。Ok,TCP串連就這樣關閉了!
整個過程Client端所經曆的狀態如下:
而Server端所經曆的過程如下:
【注意】 在TIME_WAIT狀態中,如果TCP client端最後一次發送的ACK丟失了,它將重新發送。TIME_WAIT狀態中所需要的時間是依賴於實現方法的。典型的值為30秒、1分鐘和2分鐘。等待之後串連正式關閉,並且所有的資源(包括連接埠號碼)都被釋放。
【問題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報文。