TCP建立連接的三次握手和TCP連接斷開的四次揮手
1. TCP建立連接的3次握手
2. TCP斷開連接的四次揮手
【註意】中斷連接端可以是Client端,也可以是Server端。
圖3—Client端主動發起關閉連接請求
1. 假設Client端主動發起中斷連接請求,也就是發送FIN報文。
2. Server端接到FIN報文後,意思是說"我Client端沒有數據要發給你了",但是如果你還有數據沒有發送完成,則不必急著關閉Socket,可以繼續發送數據。所以你先發送ACK,"告訴Client端,你的請求我收到了,但是我還沒準備好,請繼續你等我的消息"。這個時候Client端就進入FIN_WAIT狀態,繼續等待Server端的FIN報文。此時Server端進入ClOSE_WAIT狀態。
3當Server端確定數據已發送完成,則向Client端發送FIN報文,"告訴Client端,好了,我這邊數據發完了,準備好關閉連接了"。
4.Client端收到FIN報文後,"就知道可以關閉連接了,但是他還是不相信網絡,怕Server端不知道要關閉,所以Client端發送ACK後進入TIME_WAIT狀態,如果Server端沒有收到ACK則可以重傳。“,Server端收到ACK後,"就知道可以斷開連接了"。Client端等待了2MSL後依然沒有收到回復,則證明Server端已正常關閉,那好,我Client端也可以關閉連接了。Ok,TCP連接就這樣關閉了!
【問題1】為什麽TIME_WAIT狀態需要經過2MSL(最大報文段生存時間)才能返回到CLOSE狀態?
答:雖然按道理,四個報文都發送完畢,我們可以直接進入CLOSE狀態了,但是我們必須假象網絡是不可靠的,有可能最後一個ACK丟失。所以TIME_WAIT狀態就是用來重發可能丟失的ACK報文。
為什麽是2MSL,主要是為了考慮到如果最後一個ACK丟失,服務端會重新發FIN,客戶端等待2MSL,才能接收到服務端重新發送的FIN報文。
在服務器的日常維護過程中,會經常用到下面的命令:
netstat -n | awk ‘/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}‘
它會顯示例如下面的信息:
TIME_WAIT 814
CLOSE_WAIT 1
FIN_WAIT1 1
ESTABLISHED 634
SYN_RECV 2
LAST_ACK 1
常用的三個狀態是:ESTABLISHED 表示正在通信,TIME_WAIT 表示主動關閉,CLOSE_WAIT 表示被動關閉。
TCP建立連接的三次握手和TCP連接斷開的四次揮手