TCP三次握手與四次揮手

? ? ? ? 傳輸控制協(xié)議(TCP,Transmission Control Protocol)是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,由IETF的RFC 793定義。

? ? ? ? TCP旨在適應(yīng)支持多網(wǎng)絡(luò)應(yīng)用的分層協(xié)議層次結(jié)構(gòu)。 連接到不同但互連的計(jì)算機(jī)通信網(wǎng)絡(luò)的主計(jì)算機(jī)中的成對(duì)進(jìn)程之間依靠TCP提供可靠的通信服務(wù)。TCP假設(shè)它可以從較低級(jí)別的協(xié)議獲得簡(jiǎn)單的,可能不可靠的數(shù)據(jù)報(bào)服務(wù)。 原則上,TCP應(yīng)該能夠在從硬線連接到分組交換或電路交換網(wǎng)絡(luò)的各種通信系統(tǒng)之上操作。

? ? ? ?傳輸控制協(xié)議(TCP,Transmission Control Protocol)是為了在不可靠的互聯(lián)網(wǎng)絡(luò)上提供可靠的端到端字節(jié)流而專門設(shè)計(jì)的一個(gè)傳輸協(xié)議。

? ? ? ?互聯(lián)網(wǎng)絡(luò)與單個(gè)網(wǎng)絡(luò)有很大的不同,因?yàn)榛ヂ?lián)網(wǎng)絡(luò)的不同部分可能有截然不同的拓?fù)浣Y(jié)構(gòu)、帶寬、延遲、數(shù)據(jù)包大小和其他參數(shù)。TCP的設(shè)計(jì)目標(biāo)是能夠動(dòng)態(tài)地適應(yīng)互聯(lián)網(wǎng)絡(luò)的這些特性,而且具備面對(duì)各種故障時(shí)的健壯性。

三次握手過程理解

第一次握手:建立連接時(shí),客戶端發(fā)送syn包(syn=x)到服務(wù)器,并進(jìn)入SYN_SENT狀態(tài),等待服務(wù)器確認(rèn);SYN:同步序列編號(hào)(Synchronize Sequence Numbers)。

第二次握手:服務(wù)器收到syn包,必須確認(rèn)客戶的SYN(ack=x+1),同時(shí)自己也發(fā)送一個(gè)SYN包(syn=y),即SYN+ACK包,此時(shí)服務(wù)器進(jìn)入SYN_RECV狀態(tài);

第三次握手:客戶端收到服務(wù)器的SYN+ACK包,向服務(wù)器發(fā)送確認(rèn)包ACK(ack=y+1),此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入ESTABLISHED(TCP連接成功)狀態(tài),完成三次握手。


舉個(gè)例子

一對(duì)情侶準(zhǔn)備周天去看電影。

第一次握手 男孩發(fā)送:周天去看電影吧。

第二次握手 女孩回應(yīng):好的。

第三次握手 男孩回應(yīng):那說好了。

1、為什么不能用兩次握手進(jìn)行連接?

3次握手完成兩個(gè)重要的功能,既要雙方做好發(fā)送數(shù)據(jù)的準(zhǔn)備工作(雙方都知道彼此已準(zhǔn)備好),也要允許雙方就初始序列號(hào)進(jìn)行協(xié)商,這個(gè)序列號(hào)在握手過程中被發(fā)送和確認(rèn)。

兩次握手出現(xiàn)意外時(shí),將會(huì)出現(xiàn)資源的浪費(fèi)。

握手分為Server s,Client c。

? ? ? ? 兩次握手,當(dāng)C想要建立連接時(shí)發(fā)送一個(gè)SYN,然后等待ACK,結(jié)果這個(gè)SYN因?yàn)榫W(wǎng)絡(luò)問題沒有及時(shí)到達(dá)S,所以C在一段時(shí)間內(nèi)沒收到ACK后,再發(fā)送一個(gè)SYN,這次S順利收到,接著C也收到ACK,這時(shí)C發(fā)送的第一個(gè)SYN終于到了S,對(duì)于S來說這是一個(gè)新連接請(qǐng)求,然后S又為這個(gè)連接申請(qǐng)資源,返回ACK,然而這個(gè)SYN是個(gè)無效的請(qǐng)求,C收到這個(gè)SYN的ACK后也并不會(huì)理會(huì)它,而S卻不知道,S會(huì)一直為這個(gè)連接維持著資源,造成資源的浪費(fèi)。

三次握手出現(xiàn)錯(cuò)誤時(shí)的應(yīng)對(duì)措施

???? 第一次握手A發(fā)送SYN傳輸失敗,A,B都不會(huì)申請(qǐng)資源,連接失敗。如果一段時(shí)間內(nèi)發(fā)出多個(gè)SYN連接請(qǐng)求,那么A只會(huì)接受它最后發(fā)送的那個(gè)SYN的SYN+ACK回應(yīng),忽略其他回應(yīng)全部回應(yīng),B中多申請(qǐng)的資源也會(huì)釋放

? ? ?第二次握手B發(fā)送SYN+ACK傳輸失敗,A不會(huì)申請(qǐng)資源,B申請(qǐng)了資源,但收不到A的ACK,過一段時(shí)間釋放資源。如果是收到了多個(gè)A的SYN請(qǐng)求,B都會(huì)回復(fù)SYN+ACK,但A只會(huì)承認(rèn)其中它最早發(fā)送的那個(gè)SYN的回應(yīng),并回復(fù)最后一次握手的ACK

? ? ?第三次握手ACK傳輸失敗,B沒有收到ACK,釋放資源,對(duì)于后序的A的傳輸數(shù)據(jù)返回RST。實(shí)際上B會(huì)因?yàn)闆]有收到A的ACK會(huì)多次發(fā)送SYN+ACK,次數(shù)是可以設(shè)置的,如果最后還是沒有收到A的ACK,則釋放資源,對(duì)A的數(shù)據(jù)傳輸返回RST。

TCP的四次揮手

(1)首先客戶端想要釋放連接,向服務(wù)器端發(fā)送一段TCP報(bào)文,其中:

標(biāo)記位為FIN,表示“請(qǐng)求釋放連接“;序號(hào)為Seq=U;隨后客戶端進(jìn)入FIN-WAIT-1階段,即半關(guān)閉階段。并且停止在客戶端到服務(wù)器端方向上發(fā)送數(shù)據(jù),但是客戶端仍然能接收從服務(wù)器端傳輸過來的數(shù)據(jù)。注意:這里不發(fā)送的是正常連接時(shí)傳輸?shù)臄?shù)據(jù)(非確認(rèn)報(bào)文),而不是一切數(shù)據(jù),所以客戶端仍然能發(fā)送ACK確認(rèn)報(bào)文。

(2)服務(wù)器端接收到從客戶端發(fā)出的TCP報(bào)文之后,確認(rèn)了客戶端想要釋放連接,隨后服務(wù)器端結(jié)束ESTABLISHED階段,進(jìn)入CLOSE-WAIT階段(半關(guān)閉狀態(tài))并返回一段TCP報(bào)文。

前"兩次揮手"既讓服務(wù)器端知道了客戶端想要釋放連接,也讓客戶端知道了服務(wù)器端了解了自己想要釋放連接的請(qǐng)求。于是,可以確認(rèn)關(guān)閉客戶端到服務(wù)器端方向上的連接了

(3)服務(wù)器端自從發(fā)出ACK確認(rèn)報(bào)文之后,經(jīng)過CLOSED-WAIT階段,做好了釋放服務(wù)器端到客戶端方向上的連接準(zhǔn)備,再次向客戶端發(fā)出一段TCP報(bào)文,其中:

標(biāo)記位為FIN,ACK,表示“已經(jīng)準(zhǔn)備好釋放連接了”。注意:這里的ACK并不是確認(rèn)收到服務(wù)器端報(bào)文的確認(rèn)報(bào)文。序號(hào)為Seq=W;確認(rèn)號(hào)為Ack=U+1;表示是在收到客戶端報(bào)文的基礎(chǔ)上,將其序號(hào)Seq值加1作為本段報(bào)文確認(rèn)號(hào)Ack的值。隨后服務(wù)器端結(jié)束CLOSE-WAIT階段,進(jìn)入LAST-ACK階段。并且停止在服務(wù)器端到客戶端的方向上發(fā)送數(shù)據(jù),但是服務(wù)器端仍然能夠接收從客戶端傳輸過來的數(shù)據(jù)。

(4)客戶端收到從服務(wù)器端發(fā)出的TCP報(bào)文,確認(rèn)了服務(wù)器端已做好釋放連接的準(zhǔn)備,結(jié)束FIN-WAIT-2階段,進(jìn)入TIME-WAIT階段,并向服務(wù)器端發(fā)送一段報(bào)文,其中:

標(biāo)記位為ACK,表示“接收到服務(wù)器準(zhǔn)備好釋放連接的信號(hào)”。序號(hào)為Seq=U+1;表示是在收到了服務(wù)器端報(bào)文的基礎(chǔ)上,將其確認(rèn)號(hào)Ack值作為本段報(bào)文序號(hào)的值。確認(rèn)號(hào)為Ack=W+1;表示是在收到了服務(wù)器端報(bào)文的基礎(chǔ)上,將其序號(hào)Seq值作為本段報(bào)文確認(rèn)號(hào)的值。隨后客戶端開始在TIME-WAIT階段等待2MSL

服務(wù)器端收到從客戶端發(fā)出的TCP報(bào)文之后結(jié)束LAST-ACK階段,進(jìn)入CLOSED階段。由此正式確認(rèn)關(guān)閉服務(wù)器端到客戶端方向上的連接。

客戶端等待完2MSL之后,結(jié)束TIME-WAIT階段,進(jìn)入CLOSED階段,由此完成“四次揮手”。

后“兩次揮手”既讓客戶端知道了服務(wù)器端準(zhǔn)備好釋放連接了,也讓服務(wù)器端知道了客戶端了解了自己準(zhǔn)備好釋放連接了。于是,可以確認(rèn)關(guān)閉服務(wù)器端到客戶端方向上的連接了,由此完成“四次揮手”。

與“三次揮手”一樣,在客戶端與服務(wù)器端傳輸?shù)腡CP報(bào)文中,雙方的確認(rèn)號(hào)Ack和序號(hào)Seq的值,都是在彼此Ack和Seq值的基礎(chǔ)上進(jìn)行計(jì)算的,這樣做保證了TCP報(bào)文傳輸?shù)倪B貫性,一旦出現(xiàn)某一方發(fā)出的TCP報(bào)文丟失,便無法繼續(xù)"揮手",以此確保了"四次揮手"的順利完成。

為何要四次分手呢?

我們?cè)诖酥跋日f說TCP異常斷開的情況

TCP異常斷開

1、如果已經(jīng)建立了連接,但是一方突然出現(xiàn)故障了怎么辦?

TCP還設(shè)有一個(gè)?;钣?jì)時(shí)器,顯然,客戶端如果出現(xiàn)故障,服務(wù)器不能一直等下去,白白浪費(fèi)資源。服務(wù)器每收到一次客戶端的請(qǐng)求后都會(huì)重新復(fù)位這個(gè)計(jì)時(shí)器,時(shí)間通常是設(shè)置為2小時(shí),若兩小時(shí)還沒有收到客戶端的任何數(shù)據(jù),服務(wù)器就會(huì)發(fā)送一個(gè)探測(cè)報(bào)文段,以后每隔75秒鐘發(fā)送一次。若一連發(fā)送10個(gè)探測(cè)報(bào)文仍然沒反應(yīng),服務(wù)器就認(rèn)為客戶端出了故障,接著就關(guān)閉連接。

心跳檢測(cè)機(jī)制

在TCP網(wǎng)絡(luò)通信中,經(jīng)常會(huì)出現(xiàn)客戶端和服務(wù)器之間的非正常斷開,需要實(shí)時(shí)檢測(cè)查詢鏈接狀態(tài)。常用的解決方法就是在程序中加入心跳機(jī)制。

此外,還有Heart-Beat線程、設(shè)置TCP屬性等機(jī)制。

通俗理解

斷電、死機(jī)、這意味著所有狀態(tài)信息的失,如同-個(gè)失憶的人,對(duì)外界的一-切是陌生的,即使重新啟動(dòng)、程序征常運(yùn)行也是如此。

另一方肯定還是有正常記憶的,但雙方狀態(tài)(記憶)不對(duì)稱已經(jīng)無法完成正常意義的溝通,所以最好的方法,就是讓好的一方檢測(cè)到記憶的不對(duì)稱,然后把自己的記憶也釋放( reset) ,雙方再重新談-場(chǎng)戀爰(TCP重連)。

好的一方如何檢測(cè)呢?

TCP Keepalive

默認(rèn)情況下, TCP 120分鐘會(huì)發(fā)送檢測(cè)信號(hào),如果對(duì)方?jīng)]有回復(fù), 會(huì)重試幾次到放棄,然后宣布對(duì)方翹辮子,發(fā)送Reset釋放連接。對(duì)方收到會(huì)莫名其妙,會(huì)默默地忽視,因?yàn)閴焊鶝]有這個(gè)連接(掉電釋放掉了)。

2個(gè)小時(shí)是一個(gè)漫長(zhǎng)的等待 ,滯留的TCP會(huì)話會(huì)-直站用資源, 這是一種浪費(fèi)!

Application Keepalive

為了更快地檢測(cè)對(duì)方已經(jīng)Dead的事實(shí),應(yīng)用程序?qū)用婵梢园l(fā)送檢測(cè)信號(hào),比如5 -10分鐘檢測(cè)一次。

通過以上兩種常用方法,可以克服好的一方永久駐留在內(nèi)存里的現(xiàn)狀,釋放是唯一正確的方法 !實(shí), Application Keepalive除了檢測(cè)對(duì)方是否在線,大的作用是為了避免存在于通信雙方之間的NAT設(shè)備表超時(shí)刪除,需要周期性地刷新保活。

所以四次揮手也是為了能實(shí)時(shí)的斷開連接,釋放資源

這也是為了應(yīng)對(duì)意外情況

比如客戶端在發(fā)送一次斷開報(bào)文后直接自行斷開了連接。而這個(gè)連接服務(wù)器端卻沒有收到。

此時(shí)服務(wù)器并不知道客戶端已經(jīng)斷開了連接。在此期間會(huì)一直發(fā)送請(qǐng)求判斷客戶端是否連接。直到最后還沒有回應(yīng),才會(huì)斷開連接。

TCP協(xié)議是一種面向連接的、可靠的、基于字節(jié)流的運(yùn)輸層通信協(xié)議。TCP是全雙工模式,這就意味著,當(dāng)主機(jī)1發(fā)出FIN報(bào)文段時(shí),只是表示主機(jī)1已經(jīng)沒有數(shù)據(jù)要發(fā)送了,主機(jī)1告訴主機(jī)2,它的數(shù)據(jù)已經(jīng)全部發(fā)送完畢了;但是,這個(gè)時(shí)候主機(jī)1還是可以接受來自主機(jī)2的數(shù)據(jù);當(dāng)主機(jī)2返回ACK報(bào)文段時(shí),表示它已經(jīng)知道主機(jī)1沒有數(shù)據(jù)發(fā)送了,但是主機(jī)2還是可以發(fā)送數(shù)據(jù)到主機(jī)1的;當(dāng)主機(jī)2也發(fā)送了FIN報(bào)文段時(shí),這個(gè)時(shí)候就表示主機(jī)2也沒有數(shù)據(jù)要發(fā)送了,就會(huì)告訴主機(jī)1,我也沒有數(shù)據(jù)要發(fā)送了,之后彼此就會(huì)愉快的中斷這次TCP連接。如果要正確的理解四次分手的原理,就需要了解四次分手過程中的狀態(tài)變化。

舉個(gè)例子

本來一對(duì)情侶約好周天去看電影

如果是一次揮手即一方發(fā)送斷開請(qǐng)求之后立即關(guān)閉連接。

女孩不想去了,就發(fā)送:周天不去了,手機(jī)就關(guān)掉了(關(guān)閉連接),如果這個(gè)消息沒有發(fā)送成功。

男孩認(rèn)為約會(huì)還是算數(shù)的。就一直等待,等待超時(shí)的時(shí)候詢問:還在不在?

此時(shí)女孩已經(jīng)關(guān)機(jī)了,所以接受不到這個(gè)信息。

男孩可能會(huì)等待兩個(gè)小時(shí)之后才選擇回去。


如果是兩次揮手。

女孩不想去了,就發(fā)送:周天不去了。然后手機(jī)沒有關(guān)機(jī),想確認(rèn)男孩有沒有收到。

因?yàn)槭莾纱螕]手。男孩接到信息后回應(yīng):好的。 就選擇關(guān)機(jī)(斷開連接,這里先看成男孩已經(jīng)沒有其他數(shù)據(jù)要發(fā)送,因?yàn)槭莾纱螕]手)。但是回應(yīng)沒有發(fā)送到。

此時(shí)女孩就會(huì)一直等,并反復(fù)發(fā)送消息。但此時(shí)男孩已經(jīng)關(guān)機(jī)了。女孩可能會(huì)反復(fù)發(fā)送很長(zhǎng)時(shí)間才選擇斷開連接。


或者男孩回復(fù)好的之后,女孩也接受到了,但男孩還有話沒說完,想繼續(xù)聊一聊之前的那個(gè)話題,這個(gè)話題還很重要。但是因?yàn)閷?duì)面關(guān)閉連接也接收不到了。

(這就可能出現(xiàn)傳輸過程中數(shù)據(jù)的不完整,不滿足數(shù)據(jù)可靠)

所以要等雙方數(shù)據(jù)都傳輸完畢的四次揮手。

可以實(shí)時(shí)的關(guān)閉掉連接。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容