【Linux】三次握手

客戶端connect()向服務器發起連接,客戶端和服務器通過三次握手建立連接,被服務器listen()開機後監聽到後將套接字放到listen()已完成三次握手隊列中。

第一次握手:建立連接時,客戶端向服務器發送SYN報文(seq = j),並進入SYN_SENT狀態,等待服務器確認。

第二次握手:服務器收到SYN報文,必須確認客戶的SYN(即發送ACK報文,ack = j+1),同時自己也發送一個SYN報文(seq = k),即ACK+SYN報文,此時服務器進入SYN_RECV狀態。

第三次握手:客戶端收到服務器的SYN+ACK報文,向服務器發送確認報文ACK(ack = k+1),此報文發送完畢,客戶端和服務器進入ESTABLISHED(TCP連接成功)狀態。完成三次握手。

未完成三次握手隊列:在三次握手協議中,服務器listen()維護一個未連接隊列,該隊列爲每個客戶端的SYN包(syn=j)開設一個條目,該條目表明服務器已收到SYN包,並向客戶發出確認,正在等待客戶的確認包。這些條目所標識的連接在服務器處SYN_RECV狀態,當服務器收到客戶的確認包時,刪除該條目,服務器進入ESTABLISHED狀態。

三次握手示意圖

三次握手的作用:

使得通訊雙方都做好通訊的準備

告訴對端,本端通訊所選用的報文標識號

       防止已失效的連接請求報文段又突然傳遞到了服務端,從而產生錯誤

爲什麼是三次握手,兩次可以嗎?

不可以。主要目的是防止服務器一直等待,浪費資源。舉例說明:

客戶端發出的第一個連接請求報文段並沒有丟失,而是在某個網絡節點長時間的滯留了,以至於延誤到連接釋放以後的某個時間才送達服務器。本來這是一個早已失效的報文段,但是服務器收到此失效的連接請求報文段後,就誤以爲是客戶端再次發出了一個新的連接請求;於是就向客戶端發出確認報文段,同意建立連接。假設不採用“三次握手”,那麼只要服務器發出確認,新的連接就建立了。由於現在客戶端並沒有發出建立連接的請求,所以不會理睬服務器的確認,也不會向服務器發送數據。但服務器卻以爲新的運輸連接已經建立,並一直等待客戶端發來數據。這樣服務器的很多資源就白白浪費掉了。

採用“三次握手”的辦法可以防止上述現象發生。例如發生上述現象。客戶端不會向服務器的確認發出確認。服務器由於收不到確認,就知道客戶端並沒有要建立連接。

三次握手哪個階段會出現異常?

階段可能會出現異常。如果服務器相應的端口未打開,會回覆RST復位報文,握手失敗

此外,listen創建的監聽隊列達到上限,也可能失敗。

三次握手哪個階段容易出現攻擊?

比較典型的是SYN泛洪攻擊,或叫SYN溢出攻擊

syn溢出攻擊,即出現在第二階段,如果客戶機僞造出大量第一次的syn同步報文,服務器就會依次耗掉很多資源來保存客戶端的信息,並進行確認,實際確認是會失敗的,但失敗是需要一定時間的,因爲服務器會連續多次進行第二次握手確認後才認定失敗。那麼短時間內有大量syn同步報文涌向服務端,服務器資源可能被耗盡,就可能導致正常的客戶端得不到響應而失敗

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章