tcp握手過程

TCP結(jié)構(gòu):

1

SYN是同步的縮寫,SYN 段是發(fā)送到另一臺計(jì)算機(jī)的 TCP 數(shù)據(jù)包,請求在它們之間建立連接

ACK 是“確認(rèn)”的縮寫。 ACK 數(shù)據(jù)包是任何確認(rèn)收到一條消息或一系列數(shù)據(jù)包的 TCP 數(shù)據(jù)包

TCP三次握手如圖:

tcp三次握手

1.1第一次握手

客戶端給服務(wù)器發(fā)送一個SYN標(biāo)志位為1的 TCP/IP 數(shù)據(jù)包, 該包中客戶端的初始序列號(Sequence number = J)。

1.2第二次握手

服務(wù)器返回客戶端 SYN +ACK兩個標(biāo)志位都為為1的 TCP/IP 數(shù)據(jù)包,該包中服務(wù)器的初始序列號(Sequence number = K);同時使 Acknowledgment number = J + 1來表示確認(rèn)已收到客戶端的 SYN段。

1.3第三次握手

客戶端給服務(wù)器響應(yīng)一個ACK標(biāo)志位為1的 TCP/IP 數(shù)據(jù)包, 該包中使 Acknowledgment number = K + 1來表示確認(rèn)已收到服務(wù)器的 SYN段。

解釋一下 三次握手 和 四次揮手?

三次握手:

第一次:客戶端向服務(wù)器發(fā)送syn包,此時進(jìn)入[SYN_SENT]狀態(tài),等待服務(wù)器返回信息;此時服務(wù)端確認(rèn)了客戶端發(fā)送是正常的

第二次:服務(wù)器收到syn包,需要確認(rèn)客戶端的syn包,同時自己發(fā)出一個syn+ask包給客戶端;此時客戶端知道了自己發(fā)送、接收正常,客戶端也知道服務(wù)器發(fā)送接收也正常;但是服務(wù)器不知道客戶端接收是否正常,也不知道自己發(fā)送是否正常。

第三次:[客戶端]收到服務(wù)器的syn+ask包后,向服務(wù)器發(fā)送確認(rèn)包ask,此包發(fā)送完畢,客戶端和服務(wù)器進(jìn)入[ESTABLISHED](TCP連接成功)狀態(tài);雙方都知道對方發(fā)送和接收都正常。

為什么不能兩次握手:

假如A發(fā)出了一個由于網(wǎng)絡(luò)異常變成了失效的連接a;當(dāng)a到達(dá)B,那么只要B確認(rèn),新的連接就建立了。B會一直等待A發(fā)送數(shù)據(jù),這樣就造成了資源浪費(fèi)。

為什么不能四次握手:

3次就可以解決問題了,為什么要四次


TCP三次握手詳細(xì)解析過程:

2

1.1 第一次握手

客戶在socket() connect()后主動(active open)連接上服務(wù)器, 發(fā)送SYN ,這時客戶端的狀態(tài)是SYN_SENT

服務(wù)器在進(jìn)行socket(),bind(),listen()后等待客戶的連接,收到客戶端的 SYN 后,

1.1.1 半連接隊(duì)列(syn queue)未滿

服務(wù)器將該連接的狀態(tài)變?yōu)镾YN_RCVD, 服務(wù)器把連接信息放到半連接隊(duì)列(syn queue)里面。

1.1.2?半連接隊(duì)列(syn queue)已滿

服務(wù)器不會將該連接的狀態(tài)變?yōu)镾YN_RCVD,且將該連接丟棄(SYN flood攻擊就是利用這個原理,

對于SYN foold攻擊,應(yīng)對方法之一是使syncookies生效,將其值置1即可,路徑/proc/sys/net/ipv4/tcp_syncookies,

即使是半連接隊(duì)列syn queue已經(jīng)滿了,也可以接收正常的非惡意攻擊的客戶端的請求,

1.2 第二次握手

服務(wù)器返回SYN+ACK段給到客戶端,客戶端收到SYN+ACK段后,客戶端的狀態(tài)從SYN_SENT變?yōu)镋STABLISHED,

也即是connect()函數(shù)的返回。

1.3 第三次握手

全連接隊(duì)列(accept queue)的最大值 /proc/sys/net/core/somaxconn (默認(rèn)128)

1.3.1 全連接隊(duì)列(accept queue)未滿

服務(wù)器收到客戶端發(fā)來的ACK, 服務(wù)端該連接的狀態(tài)從SYN_RCVD變?yōu)镋STABLISHED,

然后服務(wù)器將該連接從半連接隊(duì)列(syn queue)里面移除,且將該連接的信息放到全連接隊(duì)列(accept queue)里面。

1.3.2?全連接隊(duì)列(accept queue)已滿

服務(wù)器收到客戶端發(fā)來的ACK, 不會將該連接的狀態(tài)從SYN_RCVD變?yōu)镋STABLISHED。

當(dāng)然全連接隊(duì)列(accept queue)已滿時,則根據(jù) tcp_abort_on_overflow 的值來執(zhí)行相應(yīng)動作


SYN flood攻擊

攻擊方的客戶端只發(fā)送SYN分節(jié)給服務(wù)器,然后對服務(wù)器發(fā)回來的SYN+ACK什么也不做,直接忽略掉,

不發(fā)送ACK給服務(wù)器;這樣就可以占據(jù)著服務(wù)器的半連接隊(duì)列的資源,導(dǎo)致正常的客戶端連接無法連接上服務(wù)器。

(SYN flood攻擊的方式其實(shí)也分兩種,第一種,攻擊方的客戶端一直發(fā)送SYN,對于服務(wù)器回應(yīng)的SYN+ACK什么也不做,不回應(yīng)ACK, 第二種,攻擊方的客戶端發(fā)送SYN時,將源IP改為一個虛假的IP, 然后服務(wù)器將SYN+ACK發(fā)送到虛假的IP, 這樣當(dāng)然永遠(yuǎn)也得不到ACK的回應(yīng)。)

https://blog.csdn.net/jun2016425/article/details/81506353

四次揮手:

假設(shè)Client端發(fā)起中斷連接請求,也就是發(fā)送FIN報文。

Server端接到FIN報文后,意思是說”我Client端沒有數(shù)據(jù)要發(fā)給你了”,但是如果你還有數(shù)據(jù)沒有發(fā)送完成,則不必急著關(guān)閉Socket,可以繼續(xù)發(fā)送數(shù)據(jù)。所以 Server 端會先發(fā)送ACK,”告訴Client端,你的請求我收到了,但是我還沒準(zhǔn)備好,請繼續(xù)你等我的消息”。這個時候Client端就進(jìn)入 FIN_WAIT 狀態(tài),繼續(xù)等待Server端的FIN報文。

當(dāng)Server端確定數(shù)據(jù)已發(fā)送完成,則向Client端發(fā)送FIN報文,”告訴Client端,好了,我這邊數(shù)據(jù)發(fā)完了,準(zhǔn)備好關(guān)閉連接了”。

Client端收到FIN報文后,”就知道可以關(guān)閉連接了,但是他還是不相信網(wǎng)絡(luò),怕Server端不知道要關(guān)閉,所以發(fā)送 ACK 后進(jìn)入 TIME_WAIT 狀態(tài),如果 Server 端沒有收到 ACK 則可以重傳“,Server端收到ACK后,”就知道可以斷開連接了”。

Client端等待了2MSL后依然沒有收到回復(fù),則證明Server端已正常關(guān)閉,那好,我Client端也可以關(guān)閉連接了。Ok,TCP連接就這樣關(guān)閉了!

整個過程:

A向B發(fā)起請求,表示A沒有數(shù)據(jù)要發(fā)送了:A——>B;

B向A發(fā)送信號,確認(rèn)A的斷開請求請求:B——>A;

B向A發(fā)送信號,請求斷開連接,表示B沒有數(shù)據(jù)要發(fā)送了:B——>A;

A向B發(fā)送確認(rèn)信號,同意斷開:A——>B。

為什么2、3次揮手不能合在一次揮手中?那是因?yàn)榇藭rA雖然不再發(fā)送數(shù)據(jù)了,但是還可以接收數(shù)據(jù),B可能還有數(shù)據(jù)要發(fā)送給A,所以兩次揮手不能合并為一次。

為什么揮手次數(shù)比握手多一次? 是因?yàn)槲帐诌^程,通信只需要處理連接。而揮手過程,通信需要處理數(shù)據(jù)+連接。

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

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

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