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