一圖學完!計算機網絡(TCP三次握手四次揮手)含面試題(下篇)


一圖學完!計算機網絡(TCP等)含面試題(上篇)

1.TCP三次握手

標誌位: ACK:確認序號標誌,爲1時有效,爲0則忽略。SYN:同步序號,用於建立連接

1. 客戶端發送確認序號SYN=1,初始序號seq=x的包,連接服務器的端口。此時客戶端進入SYN-SENT狀態。

2. 服務器返回確認包ack=x+1,併發送一個自己的序號seq=y。此時服務器由LISTEN變爲SYN-RCVD狀態。

3. 客戶端收到確認包後進入ESTABLISHED(連接成功)狀態,客戶端發送ACK=1,ack=y+1,序列號設置爲第二次的確認號x+1。服務器收到後也進入連接成功狀態。
在這裏插入圖片描述

建立連接三次握手解釋:
1.客戶端: 讓我們建立連接吧,我發送的信息序號會從x(seq)開始。
2.服務器: 收到,我已經準備好接受序號爲x+1(ack)的信息了,我發送的信息序號會從y(seq)開始。
3.客戶端: 很好,我也收到了你的序號,可以向我發送編號y+1(ack)的信息了。

2.TCP四次揮手

標誌位: FIN:finish標誌,用於釋放連接。(TCP連接是全雙工的,因此每個方向都必須單獨進行關閉)

1. 首先客戶端與服務器端處於連接狀態,客戶端發送FIN=1,ACK=1, seq = u,的斷開連接請求報文,客戶端進入到FIN-WAIT1狀態。

2. 服務器接收後,立即發送ACK=1,seq=v,ack=u+1 的確認收到的報文,並斷開客戶端發送信息,服務器接收信息的那一條連接,但保留服務器發送信息,進入到CLOSE-WAIT狀態。

3. 客戶端接收到第二次揮手信息進入FIN-WAIT2狀態,tcp連接進入半關閉狀態,此時只能由服務器發送數據,客戶端接收數據。

4. 之後第三次揮手是服務器端發送完畢,向客戶端發送FIN=1,ACK=1,seq=w,ack=u+1的斷開連接報文,服務器進入到LAST-ACK狀態,客戶端接收到第三次揮手信息後,發送ACK=1,seq=u+1,ack=w+1,的確認報文,進入TIME-WAIT狀態,時長2MSL,服務器接收到後,進入CLOSE狀態。
在這裏插入圖片描述
TIME-WAIT狀態: 目的是爲了防止服務器端沒有收到第四次握手的確認報文,假如沒有收到確認報文,那麼服務器的第三次揮手會超時重傳,處於TIME-WAIT的客戶端這時候可以發送確認報文,以關閉服務器,避免浪費資源。

Ex: 一個正常的TCP連接需要三次握手,首先客戶端發送一個包含SYN標誌的數據包,其後服務器返回一個SYN/ACK的應答包,表示客戶端的請求被接受,最後客戶端再返回一個確認包ACK,這樣才完成TCP連接。在服務器端發送應答包後,如果客戶端不發出確認,服務器會等待到超時,期間這些半連接狀態都保存在一個空間有限的緩存隊列中;如果大量的SYN包發到服務器端後沒有應答,就會使服務器端的TCP資源迅速耗盡,導致正常的連接不能進入,甚至會導致服務器的系統崩潰。

3.問題分析

3.1.爲什麼不能用兩次握手進行連接?

參考:
爲了實現可靠數據傳輸, TCP 協議的通信雙方, 都必須維護一個序列號, 以標識發送出去的數據包中, 哪些是已經被對方收到的。 三次握手的過程即是通信雙方相互告知序列號起始值, 並確認對方已經收到了序列號起始值的必經步驟。
如果只是兩次握手, 至多隻有連接發起方的起始序列號能被確認, 另一方選擇的序列號則得不到確認。
三次握手完成了兩個重要功能。令雙方都知道彼此已準備好,同時也確認了雙方發送的序列號。另一個原因是可能發生死鎖(防止已失效的請求連接報文忽然又傳送到了,從而產生錯誤)。
參考連接

3.2.如果已經建立了連接,但是客戶端突然出現故障怎麼辦?

參考: Keepalive(保活定時器)
Keepalive的使用: 檢測tcp socket並檢測連接是否在運行或者是否被破壞
TCP還設有一個保活計時器,顯然,客戶端如果出現故障,服務器不能一直等下去,白白浪費資源。服務器每收到一次客戶端的請求後都會重新復位這個計時器,時間通常是設置爲2小時,若兩小時還沒有收到客戶端的任何數據,服務器就會發送一個探測報文段,以後每隔75秒鐘發送一次。若一連發送9個探測報文仍然沒反應(總共7200+75*9的時間),服務器就認爲客戶端出了故障,接着就關閉連接。
相關參數:

tcp_keepalive_time 7200// 距離上次傳送數據多少時間未收到新報文判斷爲開始檢測,單位秒,默認7200s
tcp_keepalive_intvl 75// 檢測開始每多少時間發送心跳包,單位秒,默認75s
tcp_keepalive_probes 9// 發送幾次心跳包對方未響應則close連接,默認9次

3.3.SYN Flood攻擊

說明: 三次握手是有缺陷的,在第二次握手中,當服務器發送了SYN+ACK報文後,若該連接的定時器超過超時重傳時間服務器會對報文進行重傳,當重傳次數超過一定次數後,服務器認爲TCP連接超時,而後才銷燬套接字,釋放TCP,如果攻擊者用很快的速度,連續對目標服務器開放的端口發送SYN報文,服務器的所有資源將被消耗,以至於不能接收其他客戶的正常連接請求。

攻擊檢測以及防禦手段:
目前對於SYN Flood攻擊一般通過實時檢測tcp的新建連接速率來判斷。防禦的前提是區分出哪些請求是合法的,哪些是SYN泛洪,下面是實現SYN cookies的三種不同方式。

方法一:(reset認證)
1、當安全設備獲取到發往服務器的SYN報文後,設備模擬服務器端會給此源IP回覆ACK=Cookie的SYN/ACK報文
2、正常客戶端會回覆RST報文,攻擊流不會回覆
3、安全設備收到RST報文並校驗後可把正確報文的客戶端IP加入到白名單
4、後續安全設備放行屬於該IP的正常流量

方法二:(cookie源認證)
1、當安全設備獲取到發往服務器的SYN報文後,設備模擬服務器端會給此源IP回覆ACK=Cookie的SYN/ACK報文
2、正常客戶端回覆ACK報文,確認序號爲Cookie+1
3、安全設備收到ACK報文,並校驗無誤後,將該客戶端的IP加入到白名單,並向客戶端發送RST報文斷開連接
4、後續安全設備放行屬於該IP的正常流量

方法三:
1、當安全設備獲取到發往服務器的SYN報文後,設備模擬服務器給源IP回覆seq=Cookie的SYN/ACK報文
2、正常客戶端回覆ACK報文,確認序號爲Cookie+1
3、安全設備收到ACK報文並校驗無誤後,設備與服務發送連接請求,通過三次握手後與服務器建立起連接
4、客戶端與防火牆之間建立了連接,防火牆與服務器之間也建立了連接,客戶端與服務器間關於此次連接的後續數據報文都通過安全設備代理轉發

3.4.TCP粘包半粘包和拆包問題

在這裏插入圖片描述

如圖: 假設客戶端分別發送了兩個數據包D1和D2給服務端,由於服務端一次讀取到字節數是不確定的
故可能存在以下四種情況:
1.服務端分兩次讀取到了兩個獨立的數據包,分別是D1和D2,沒有粘包和拆包

2.服務端一次接受到了兩個數據包,D1和D2粘合在一起,稱之爲TCP粘包

3.服務端分兩次讀取到了數據包,第一次讀取到了完整的D1包和D2包的部分內容,第二次讀取到了D2包的剩餘內容,這稱之爲TCP拆包

4.服務端分兩次讀取到了數據包,第一次讀取到了D1包的部分內容D1_1,第二次讀取到了D1包的剩餘部分內容D1_2和完整的D2包。

PS: 特別要注意的是,如果TCP的接受滑窗非常小,而數據包D1和D2比較大,很有可能會發生第五種情況,即服務端分多次才能將D1和D2包完全接受,期間發生多次拆包。

粘包問題:
如果TCP數據報很短,遠小於套接字緩衝區的大小,TCP將多次寫入緩衝區的數據一次發送出去。將會發生粘包現象。
接收數據端的應用層沒有及時的讀取緩衝區中的數據,也會發生粘包。

拆包問題:
要發送的數據大於TCP發送緩衝區剩餘空間的大小,將會發生拆包。
要發送的數據大於MSS(最大報文長度),TCP在傳輸前將進行拆包。

解決方法:
在報頭首部添加數據包的長度。
發送端將每個數據包封裝爲固定長度(不夠的的可以用0來補充)
特殊字符來設置邊界進行控制。

在這裏插入圖片描述
有什麼錯誤或者補充請留言。

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