優(yōu)雅地說再見——TCP協(xié)議四次揮手
優(yōu)雅地說再見
不辭而別,總是容易讓人猝不及防。當(dāng)我們不得結(jié)束一段愉快的聊天,離開一個讓人難以割舍的城市,你會怎么做?
當(dāng)然是要學(xué)會,優(yōu)雅地說再見了。
《禮貌地說你好——TCP協(xié)議三次握手》一文中已經(jīng)介紹了,TCP協(xié)議是如何建立連接的。建立連接后,數(shù)據(jù)傳輸完成,我們又該如何優(yōu)雅地關(guān)閉連接呢?
念念不忘——TCP的四次揮手
第一次揮手
客戶端準備關(guān)閉連接時,則會向服務(wù)端發(fā)送FIN=1的數(shù)據(jù)包,并且進入FIN_WAIT_1狀態(tài)。
第二次揮手
服務(wù)端收到客戶端的FIN=1的數(shù)據(jù)包后,則會向客戶端響應(yīng)一個ACK數(shù)據(jù)包,并進入準備關(guān)閉連接的狀態(tài)。服務(wù)端此時則會開始準備停止數(shù)據(jù)傳輸。
客戶端收到服務(wù)端響應(yīng)的ACK數(shù)據(jù)包后,則進入FIN_WAIT_2的狀態(tài)。此時,仍然有可能存在數(shù)據(jù)傳輸,需要等待服務(wù)端真正停止數(shù)據(jù)傳輸時才能進入關(guān)閉狀態(tài)。
第三次揮手
服務(wù)端處理完數(shù)據(jù)傳輸則會向客戶端發(fā)送一個FIN數(shù)據(jù)包,并進入LASK_ACK狀態(tài),表示服務(wù)端已經(jīng)進入連接關(guān)閉狀態(tài)。
第四次揮手
客戶端收到FIN數(shù)據(jù)包后,則可以確認數(shù)據(jù)傳輸已經(jīng)完全停止,進入TIME_WAIT狀態(tài),并向服務(wù)端響應(yīng)ACK數(shù)據(jù)包。等待2MSL(Maximum Segment Lifetime,最大報文生存時間)后,連接才真正關(guān)閉,進入CLOSE狀態(tài)。
服務(wù)端接收到ACK數(shù)據(jù)包后則斷開連接,進入CLOSE狀態(tài)。
重試與容錯
當(dāng)FIN數(shù)據(jù)包發(fā)送出去后,長時間未收到ACK響應(yīng)的數(shù)據(jù)包,都會觸發(fā)超時重傳。
客戶端接受到FIN指令后為什么不是立即關(guān)閉連接,而要等待2MSL時間再關(guān)閉?
假設(shè)客戶端沒有TIME_WAIT的狀態(tài),而是里面關(guān)閉連接,此時如果客戶端立馬重新建立連接,連接建立成功后,又收到上一個關(guān)閉連接的數(shù)據(jù)包,并向服務(wù)端響應(yīng)了ACK數(shù)據(jù)包,則會導(dǎo)致服務(wù)端的數(shù)據(jù)混亂。
總結(jié)
TCP協(xié)議關(guān)閉連接的時候,由于可能正在進行數(shù)據(jù)傳輸,客戶端和服務(wù)端都會先進入等待關(guān)閉連接的過程。
當(dāng)客戶端或者服務(wù)端發(fā)送FIN數(shù)據(jù)包未在一定的時間內(nèi)收到ACK響應(yīng)包,則會進行重試。
客戶端最后收到服務(wù)端的FIN數(shù)據(jù)包后,會先進入TIME_WAIT的狀態(tài)等待2MSL(最大報文生存周期)。以防止,因為網(wǎng)絡(luò)延遲,消息傳輸超時等問題導(dǎo)致的消息傳輸錯亂的問題的發(fā)生。