tcp 二次握手时延_一篇搞懂TCP的三次握手 四次挥手
TCP的三次握手四次揮手,估計大家都聽過。但是真的能把每一步說明白的人比較少。我還記得在之前面試的時候被面試官一頓問,然后一臉懵B... 都是大學(xué)沒好好上課 ,這篇文章就跟大家講講到底這三握四揮是在搞什么飛機(jī)。
三次握手
握手是指的雙方進(jìn)行連接的操作。
三次握手(圖片來自網(wǎng)絡(luò))為什么是三次握手
確認(rèn)通信能力
我們要明白,如果需要進(jìn)行通信,首先需要保證的是雙方都具有發(fā)信和收信能力。在不知雙方能力狀態(tài)下進(jìn)行的通信都是無法保證可靠性和通信效率的。那么通信雙方如何確認(rèn)對方的通信能力呢?
防止產(chǎn)生臟數(shù)據(jù)連接
網(wǎng)絡(luò)通信情況復(fù)雜,不可能保證每一消息都能正常到達(dá)其目的地。在TCP連接中,TTL的網(wǎng)絡(luò)報文的生存時間一般都會比TCP的連接超時時間要長。這樣就有可能出現(xiàn)一個問題。A在發(fā)送第一次連接請求時,可能網(wǎng)絡(luò)擁塞,導(dǎo)致數(shù)據(jù)包未短時間內(nèi)到達(dá)。到達(dá)超時時間后,A又發(fā)送了一次連接請求,這次正常進(jìn)行連接。連接結(jié)束斷開后,A的第一次連接請求到達(dá)B,B返回ack。如果是兩次握手,A通過當(dāng)前的狀態(tài),直接拒絕B的請求,但B會單方面認(rèn)為連接已經(jīng)建立,實際上并不是...
每一次握手到底是傳輸了什么?
想知道除了ip和端口號,每次傳輸?shù)男畔⑹鞘裁?#xff0c;我們首先得知道TCP傳輸信息的結(jié)構(gòu)。
TCP報文結(jié)構(gòu)(圖片來源于網(wǎng)絡(luò))第一次握手
- 首先會將TCP的header部分的控制位(上圖的flags)中的SYN置為1。表示希望建立連接。
- 還有一個重要的數(shù)據(jù),seq,即序號。這個東西是干嘛用的呢?這個涉及到TCP安全性和可靠性,與ack即確認(rèn)號緊密相關(guān)。TCP在傳輸數(shù)據(jù)時,如果數(shù)據(jù)比較大,會進(jìn)行拆分操作,將大數(shù)據(jù)拆成一個個小的數(shù)據(jù)包。序號就是在這個時候用的。我們必須要知道這個包的順序是什么,才能把真正的數(shù)據(jù)在服務(wù)端還原。seq的順序并不是從0或者1開始的,而是一個隨機(jī)值。因為如果序號從1開始,那么整個通信的過程非常容易被預(yù)測。正因為是隨機(jī)的,所以對方不知道你的seq,所以我們需要在開始收發(fā)數(shù)據(jù)之前,將seq先發(fā)送給對方。序號的初始值的傳遞就是通過SYN=1的操作傳遞的。
客戶端此時處于同步狀態(tài),即可以建立連接。服務(wù)端處于監(jiān)聽狀態(tài)。
第二次握手
- 標(biāo)志位。因為已經(jīng)收到了客戶端的建立連接請求。所以必須要發(fā)送ack,以告知客戶端自己已經(jīng)收到消息。所以ACK的標(biāo)志位要置為1,且SYN也是1,因為還未建立連接。
- seq。同第一次握手一樣,也是一個隨機(jī)值(TCP為全雙工,所以雙方都需要保留seq方便處理數(shù)據(jù)包)。
- ack。是對客戶端發(fā)過來的序列號進(jìn)行計算得到的。
服務(wù)端處于SYN接收狀態(tài)。
第三次握手
- 標(biāo)志位。此時只需要ACK=1。SYN已經(jīng)不需要了,雙方已經(jīng)同步完seq等信息。
- seq。可以說是第二次握手收到的ack。
- ack。是對第二次握手收到的序列號進(jìn)行計算得到的。用以告知已收到二次握手信息。
客戶端處于連接建立狀態(tài),服務(wù)端收到信息之后也會進(jìn)入連接建立狀態(tài),雙方可以進(jìn)行通信。
四次揮手
TCP連接在數(shù)據(jù)傳輸完成之后需要關(guān)閉,不然會一直占用系統(tǒng)資源。TCP的連接關(guān)閉需要四次通信才行,分手也是個麻煩事兒。
為什么四次才能斷開連接呢?
分手這件事情,兩邊都說明白,分別斷開即可。但是想要確認(rèn)對方都要斷開,那么一次兩次是不夠的。
四次揮手(圖片來自網(wǎng)絡(luò))我們還是拿A、B來舉例。假設(shè)A要主動斷開和B的連接。
請求發(fā)送的信息是什么?
關(guān)閉連接抓包關(guān)閉由哪方開始?
答案是哪邊都可以,無論是客戶端還是服務(wù)器端,都可以主動發(fā)起關(guān)閉請求。發(fā)起關(guān)閉請求的前提是數(shù)據(jù)發(fā)送完畢,不一定非得等待對方確認(rèn)完成。
第一次揮手
假設(shè)客戶端發(fā)起關(guān)閉請求。那么客戶端發(fā)完消息后,會進(jìn)入FIN_WAIT階段。此處已經(jīng)無法再發(fā)送應(yīng)用程序消息,只能處理關(guān)閉相關(guān)信息。
第二次揮手
服務(wù)端收到第一次揮手消息后,返回收到消息的ack。服務(wù)端會進(jìn)入CLOSE_WAIT階段。這個階段是等待關(guān)閉階段,通知應(yīng)用程序發(fā)送剩余數(shù)據(jù),處理現(xiàn)場信息,關(guān)閉相應(yīng)資源。
第三次揮手
你應(yīng)該有點好奇為什么第三次揮手和第二次揮手都是同一個服務(wù)。第二次主要是一個ack響應(yīng),第三次主要是一個服務(wù)端關(guān)閉通知消息。兩者目的不同。等到三次揮手完畢,那么服務(wù)端會進(jìn)入LAST_ACK狀態(tài),即等待最后客戶端(主動發(fā)起關(guān)閉的一方)的ack確認(rèn)。
第四次揮手
第四次揮手是主動發(fā)起關(guān)閉的一方A,對被動關(guān)閉一方B的FIN消息的確認(rèn)。第四次信息發(fā)送完成后,A會進(jìn)入TIME_WAIT階段,而不是直接刪除套接字。具體原因我們在下面講。收到第四次揮手信息后,B會直接進(jìn)行關(guān)閉操作。
為什么會有TIME_WAIT?
還是那句話,網(wǎng)絡(luò)并不是一個理想世界,任何異常情況都有可能發(fā)生。為了保證TCP連接能夠正常關(guān)閉,主動發(fā)起關(guān)閉方不能直接刪除套接字,而是需要經(jīng)過一段時間等待。這個時間一般是2MSL(Maxumun Segment Lifetime 最大報文生存時間)。原因如下
- 確認(rèn)被動關(guān)閉方能夠正常進(jìn)入關(guān)閉狀態(tài)。假設(shè)B未收到A最后的一個ack,會再次發(fā)送FIN消息(第三次揮手),如果A已經(jīng)CLOSE了,那么B就會一直重試發(fā)送。所以A必須要進(jìn)行一段時間的等待。
- 防止失效請求。假設(shè)A關(guān)閉了此次連接,又重新在原來的端口號上開啟了新的連接。原來在網(wǎng)絡(luò)上發(fā)送的一些包(已失效但未超過ttl)到來之后,無法進(jìn)行區(qū)分是否是正常的包,導(dǎo)致數(shù)據(jù)混亂。
舉個例子來證明沒有TIME_WAIT的情況。
所以TIME_WAIT也是為了防止上面的誤刪除。
總結(jié)
在并發(fā)量很高的時候,熟悉TCP的原理和參數(shù)調(diào)優(yōu)變得尤為重要。我們關(guān)注的不僅僅是幾次握手、幾次揮手,也應(yīng)該關(guān)注一些細(xì)節(jié),細(xì)節(jié)決定成敗。更應(yīng)該多問問為什么如此設(shè)計,能解決什么問題。
后續(xù)
后續(xù)主要是與大家分享討論一下對TCP的滑動窗口機(jī)制和可靠性保障的理解。如果有時間,可以跟大家分享一下TCP的參數(shù)等配置相關(guān)內(nèi)容。
一個分享Java后端知識的原創(chuàng)公眾號總結(jié)
以上是生活随笔為你收集整理的tcp 二次握手时延_一篇搞懂TCP的三次握手 四次挥手的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 打款到公户和私人账户的区别
- 下一篇: 版本变迁_上新了!隋唐洛阳城应天门3D投