TCP的3次握手和4次揮手過(guò)程

關(guān)注:CodingTechWork,一起學(xué)習(xí)進(jìn)步。

??本文主要介紹TCP連接三次握手和四次揮手的機(jī)制。

TCP三次握手

剖析三次握手機(jī)制

??首先Client端發(fā)送連接請(qǐng)求報(bào)文,Server端接受連接后回復(fù)ACK報(bào)文,并為這次連接分配資源。Client端接收到ACK報(bào)文后也向Server端發(fā)生ACK報(bào)文,并分配資源,這樣TCP連接就建立了。

TCP 三次握手過(guò)程

??最初兩端的TCP進(jìn)程都處于CLOSED關(guān)閉狀態(tài),A主動(dòng)打開連接,而B被動(dòng)打開連接。(A、B關(guān)閉狀態(tài)CLOSED** —> **B收聽狀態(tài)LISTEN —> A同步已發(fā)送狀態(tài)SYN-SENT —> B同步收到狀態(tài)SYN-RCVD —> A、B連接已建立狀態(tài)ESTABLISHED)

三次握手過(guò)程

??B的TCP服務(wù)器進(jìn)程先創(chuàng)建傳輸控制塊TCB,準(zhǔn)備接受客戶進(jìn)程的連接請(qǐng)求。然后服務(wù)器進(jìn)程就處于LISTEN(收聽)狀態(tài),等待客戶的連接請(qǐng)求。若有,則作出響應(yīng)。

  1. 第一次握手:A的TCP客戶端進(jìn)程也是首先創(chuàng)建傳輸控制塊TCB,A將標(biāo)志位SYN置為1,隨機(jī)產(chǎn)生一個(gè)值seq=x,然后向B發(fā)出連接請(qǐng)求報(bào)文段(首部的同步位SYN=1,初始序號(hào)seq=x),SYN=1的報(bào)文段不能攜帶數(shù)據(jù),但要消耗掉一個(gè)序號(hào),此時(shí)TCP客戶進(jìn)程進(jìn)入SYN-SENT(同步已發(fā)送)狀態(tài)。
  2. 第二次握手:服務(wù)端B收到連接請(qǐng)求報(bào)文段后,由標(biāo)志位SYN=1得知Client請(qǐng)求建立連接,Server將標(biāo)志位SYN和ACK都置為1,確認(rèn)號(hào)ack=x+1,隨機(jī)產(chǎn)生一個(gè)值作為初始序號(hào)seq=y,如同意建立連接,則向A發(fā)送確認(rèn)報(bào)文段(SYN=1,ACK=1,ack=x+1,seq=y)確認(rèn)連接,操作系統(tǒng)為該TCP連接分配TCP緩存和變量,此時(shí)TCP服務(wù)器進(jìn)程進(jìn)入SYN-RCVD(同步收到)狀態(tài)。
  3. 第三次握手:客戶端A收到服務(wù)端B的確認(rèn)后,檢查ack是否為x+1,ACK是否為1,如果正確則將標(biāo)志位ACK置為1,確認(rèn)號(hào)ack置為y+1,序號(hào)seq置為x+1,并且此時(shí)操作系統(tǒng)為該TCP連接分配TCP緩存和變量,要向B給出確認(rèn)報(bào)文段(ACK=1,ack=y+1,seq=x+1)。TCP連接已經(jīng)建立,A進(jìn)入ESTABLISHED(已建立連接)。當(dāng)B收到A的確認(rèn)后,也進(jìn)入ESTABLISHED狀態(tài)。

流程串

??A和B都處于CLOSED狀態(tài) —> B創(chuàng)建TCB,處于LISTEN狀態(tài),等待A請(qǐng)求 —> A創(chuàng)建TCB,發(fā)送連接請(qǐng)求(SYN=1,seq=x),進(jìn)入SYN-SENT狀態(tài) —> B收到連接請(qǐng)求,向A發(fā)送確認(rèn)(SYN=ACK=1,確認(rèn)號(hào)ack=x+1,初始序號(hào)seq=y),進(jìn)入SYN-RCVD狀態(tài) —> A收到B的確認(rèn)后,給B發(fā)出確認(rèn)(ACK=1,ack=y+1,seq=x+1),A進(jìn)入ESTABLISHED狀態(tài) —> B收到A的確認(rèn)后,進(jìn)入ESTABLISHED狀態(tài)。

TCB傳輸控制塊

??Transmission Control Block,存儲(chǔ)每一個(gè)連接中的重要信息,如TCP連接表,到發(fā)送和接收緩存的指針,到重傳隊(duì)列的指針,當(dāng)前的發(fā)送和接收序號(hào)。

四次揮手

剖析四次揮手機(jī)制

??我們通過(guò)Client端和Server端的對(duì)白來(lái)了解一下TCP四次揮手機(jī)制是怎樣的。

??假設(shè)Client端發(fā)起中斷連接請(qǐng)求,也就是發(fā)送FIN報(bào)文。Server端接到FIN報(bào)文后,了解Client的意思是說(shuō):"Server端,你好,我沒(méi)有數(shù)據(jù)要發(fā)給你了,但是如果你Server端還有數(shù)據(jù)沒(méi)有發(fā)送完成,則不必急著關(guān)閉Socket,可以繼續(xù)發(fā)送數(shù)據(jù)。

??所以Server端先發(fā)送ACK告訴Client端:"Client端,你好,你的請(qǐng)求我收到了,但是我還沒(méi)準(zhǔn)備好,請(qǐng)繼續(xù)你等我的消息"。這個(gè)時(shí)候Client端就進(jìn)入FIN_WAIT狀態(tài),繼續(xù)等待Server端的FIN報(bào)文。

??當(dāng)Server端確定數(shù)據(jù)已發(fā)送完成,則向Client端發(fā)送FIN報(bào)文,告訴Client端:"Server端,你好,我這邊數(shù)據(jù)發(fā)完了,準(zhǔn)備好關(guān)閉連接了"。
??Client端收到FIN報(bào)文后,知道無(wú)數(shù)據(jù)再傳了,可以關(guān)閉連接了。但是他還是不相信網(wǎng)絡(luò),怕Server端不知道要關(guān)閉,所以發(fā)送ACK后進(jìn)入TIME_WAIT狀態(tài),如果Server端沒(méi)有收到ACK則可以重傳。Server端收到ACK后,也知道Client確認(rèn)斷開連接了。Client端等待了2MSL后依然沒(méi)有收到Server端回復(fù),則證明Server端已正常關(guān)閉,心想,這次我Client端可以放心關(guān)閉連接了。Ok,至此TCP連接就這樣關(guān)閉了!

TCP 四次揮手過(guò)程

??數(shù)據(jù)傳輸結(jié)束后,通信的雙方都可釋放連接,A和B都處于ESTABLISHED狀態(tài)。(A、B連接建立狀態(tài)ESTABLISHED —> A終止等待1狀態(tài)FIN-WAIT-1 —> B關(guān)閉等待狀態(tài)CLOSE-WAIT —> A終止等待2狀態(tài)FIN-WAIT-2——B最后確認(rèn)狀態(tài)LAST-ACK —> A時(shí)間等待狀態(tài)TIME-WAIT —> B、A關(guān)閉狀態(tài)CLOSED)

四次揮手流程

  1. 第一次揮手:客戶端A的應(yīng)用進(jìn)程先向服務(wù)端TCP發(fā)出連接釋放報(bào)文段(FIN=1,序號(hào)seq=u),并停止再發(fā)送數(shù)據(jù),主動(dòng)關(guān)閉TCP連接,進(jìn)入FIN-WAIT-1(終止等待1)狀態(tài),等待服務(wù)端B的確認(rèn)。
  2. 第二次揮手:服務(wù)端B收到連接釋放報(bào)文段后即發(fā)出確認(rèn)報(bào)文段(ACK=1,確認(rèn)號(hào)ack=u+1,序號(hào)seq=v),服務(wù)端B進(jìn)入CLOSE-WAIT(關(guān)閉等待)狀態(tài),此時(shí)的TCP處于半關(guān)閉狀態(tài)。A收到B的確認(rèn)后,進(jìn)入FIN-WAIT-2(終止等待2)狀態(tài),等待B發(fā)出的連接釋放報(bào)文段。
  3. 第三次揮手:服務(wù)端B沒(méi)有要向客戶端A發(fā)出的數(shù)據(jù),B發(fā)出連接釋放報(bào)文段 (FIN=1,ACK=1,序號(hào)seq=w,確認(rèn)號(hào)ack=u+1),B進(jìn)入LAST-ACK(最后確認(rèn))狀態(tài),等待A的確認(rèn)。
  4. 第四次揮手:客戶端A收到服務(wù)端B的連接釋放報(bào)文段后,對(duì)此發(fā)出確認(rèn)報(bào)文段(ACK=1,seq=u+1,ack=w+1),A進(jìn)入TIME-WAIT(時(shí)間等待)狀態(tài)。此時(shí)TCP未釋放掉,需要經(jīng)過(guò)時(shí)間等待計(jì)時(shí)器設(shè)置的時(shí)間2MSL后,A才進(jìn)入CLOSED狀態(tài)。

流程串

??A和B處于ESTABLISHED狀態(tài) —> A發(fā)出連接釋放報(bào)文段并處于FIN-WAIT-1狀態(tài) —> B發(fā)出確認(rèn)報(bào)文段且進(jìn)入CLOSE-WAIT狀態(tài) —> A收到確認(rèn)后,進(jìn)入FIN-WAIT-2狀態(tài),等待B的連接釋放報(bào)文段 —> B沒(méi)有要向A發(fā)出的數(shù)據(jù),B發(fā)出連接釋放報(bào)文段且進(jìn)入LAST-ACK狀態(tài) —> A發(fā)出確認(rèn)報(bào)文段且進(jìn)入TIME-WAIT狀態(tài) —> B收到確認(rèn)報(bào)文段后進(jìn)入CLOSED狀態(tài) —> A經(jīng)過(guò)等待計(jì)時(shí)器時(shí)間2MSL后,進(jìn)入CLOSED狀態(tài)。

Q&A

為什么A還要發(fā)送一次確認(rèn)呢?可以二次握手嗎?

??主要為了防止已失效的連接請(qǐng)求報(bào)文段突然又傳送到了B,因而產(chǎn)生錯(cuò)誤。如A發(fā)出連接請(qǐng)求,但因連接請(qǐng)求報(bào)文丟失而未收到確認(rèn),于是A再重傳一次連接請(qǐng)求。后來(lái)收到了確認(rèn),建立了連接。數(shù)據(jù)傳輸完畢后,就釋放了連接,A工發(fā)出了兩個(gè)連接請(qǐng)求報(bào)文段,其中第一個(gè)丟失,第二個(gè)到達(dá)了B,但是第一個(gè)丟失的報(bào)文段只是在某些網(wǎng)絡(luò)結(jié)點(diǎn)長(zhǎng)時(shí)間滯留了,延誤到連接釋放以后的某個(gè)時(shí)間才到達(dá)B,此時(shí)B誤認(rèn)為A又發(fā)出一次新的連接請(qǐng)求,于是就向A發(fā)出確認(rèn)報(bào)文段,同意建立連接。

??不可以二次握手就建立連接,如果不采用三次握手,只要B發(fā)出確認(rèn),就建立新的連接了的話,如果此時(shí)A不理睬B的確認(rèn),且不發(fā)送數(shù)據(jù),則B一致等待A發(fā)送數(shù)據(jù),浪費(fèi)資源。

Server端易受到SYN攻擊?

??服務(wù)器端的資源分配是在二次握手時(shí)分配的,而客戶端的資源是在完成三次握手時(shí)分配的,所以服務(wù)器容易受到SYN洪泛攻擊,SYN攻擊就是Client在短時(shí)間內(nèi)偽造大量不存在的IP地址,并向Server不斷地發(fā)送SYN包,Server則回復(fù)確認(rèn)包,并等待Client確認(rèn),由于源地址不存在,因此Server需要不斷重發(fā)直至超時(shí),這些偽造的SYN包將長(zhǎng)時(shí)間占用未連接隊(duì)列,導(dǎo)致正常的SYN請(qǐng)求因?yàn)殛?duì)列滿而被丟棄,從而引起網(wǎng)絡(luò)擁塞甚至系統(tǒng)癱瘓。

??防范SYN攻擊措施:降低主機(jī)的等待時(shí)間使主機(jī)盡快的釋放半連接的占用,短時(shí)間受到某IP的重復(fù)SYN則丟棄后續(xù)請(qǐng)求。

為什么A在TIME-WAIT狀態(tài)必須等待2MSL的時(shí)間?

??MSL最長(zhǎng)報(bào)文段壽命Maximum Segment Lifetime,MSL=2

??兩個(gè)理由:1)保證客戶端A發(fā)送的最后一個(gè)ACK報(bào)文段能夠到達(dá)服務(wù)端B。2)防止“已失效的連接請(qǐng)求報(bào)文段”出現(xiàn)在本連接中。

  1. 這個(gè)ACK報(bào)文段有可能丟失,使得處于LAST-ACK狀態(tài)的B收不到對(duì)已發(fā)送的FIN+ACK報(bào)文段的確認(rèn),B超時(shí)重傳FIN+ACK報(bào)文段,而A能在2MSL時(shí)間內(nèi)收到這個(gè)重傳的FIN+ACK報(bào)文段,接著A重傳一次確認(rèn),重新啟動(dòng)2MSL計(jì)時(shí)器,最后A和B都進(jìn)入到CLOSED狀態(tài),若A在TIME-WAIT狀態(tài)不等待一段時(shí)間,而是發(fā)送完ACK報(bào)文段后立即釋放連接,則無(wú)法收到B重傳的FIN+ACK報(bào)文段,所以不會(huì)再發(fā)送一次確認(rèn)報(bào)文段,則B無(wú)法正常進(jìn)入到CLOSED狀態(tài)。
  2. 在發(fā)送完最后一個(gè)ACK報(bào)文段后,再經(jīng)過(guò)2MSL,就可以使本連接持續(xù)的時(shí)間內(nèi)所產(chǎn)生的所有報(bào)文段都從網(wǎng)絡(luò)中消失,使下一個(gè)新的連接中不會(huì)出現(xiàn)這種舊的連接請(qǐng)求報(bào)文段。

為什么連接的時(shí)候是三次握手,關(guān)閉的時(shí)候卻是四次握手?

??因?yàn)楫?dāng)Server端收到Client端的SYN連接請(qǐng)求報(bào)文后,可以直接發(fā)送SYN+ACK報(bào)文。其中ACK報(bào)文是用來(lái)應(yīng)答的,SYN報(bào)文是用來(lái)同步的。但是關(guān)閉連接時(shí),當(dāng)Server端收到FIN報(bào)文時(shí),很可能并不會(huì)立即關(guān)閉SOCKET,所以只能先回復(fù)一個(gè)ACK報(bào)文,告訴Client端,"你發(fā)的FIN報(bào)文我收到了"。只有等到我Server端所有的報(bào)文都發(fā)送完了,我才能發(fā)送FIN報(bào)文,因此不能一起發(fā)送。故需要四步握手。

為什么TIME_WAIT狀態(tài)需要經(jīng)過(guò)2MSL(最大報(bào)文段生存時(shí)間)才能返回到CLOSE狀態(tài)?

??雖然按道理,四個(gè)報(bào)文都發(fā)送完畢,我們可以直接進(jìn)入CLOSE狀態(tài)了,但是我們必須假象網(wǎng)絡(luò)是不可靠的,有可以最后一個(gè)ACK丟失。所以TIME_WAIT狀態(tài)就是用來(lái)重發(fā)可能丟失的ACK報(bào)文。

最后編輯于
?著作權(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ù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、TCP狀態(tài)linux查看tcp的狀態(tài)命令:1)、netstat -nat 查看TCP各個(gè)狀態(tài)的數(shù)量2)、lso...
    北辰青閱讀 9,740評(píng)論 0 11
  • 最近在惡補(bǔ)計(jì)算機(jī)網(wǎng)絡(luò)方面的知識(shí),之前對(duì)于TCP的三次握手和四次分手也是模模糊糊,對(duì)于其中的細(xì)節(jié)更是渾然不知,最近看...
    微醺歲月閱讀 9,669評(píng)論 4 128
  • 概述 總結(jié)一下TCP中3次握手過(guò)程,以及其原生的缺陷 引起的SYN Flood的介紹【1】TCP三次握手【2】SY...
    DDB_CS閱讀 963評(píng)論 0 2
  • 18.1 引言 TCP是一個(gè)面向連接的協(xié)議。無(wú)論哪一方向另一方發(fā)送數(shù)據(jù)之前,都必須先在雙方之間建立一條連接。本章將...
    張芳濤閱讀 3,538評(píng)論 0 13
  • 操場(chǎng)上涌動(dòng)的人頭 擺著各種姿勢(shì)做著各種鬼臉 那是記憶中唯一沒(méi)有泛黃的六月 因?yàn)榍啻簾o(wú)敵 大多沒(méi)有淚水四溢 梧桐的夢(mèng)...
    小狂欣閱讀 227評(píng)論 0 1

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