自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

TCP三次握手、四次揮手出現(xiàn)意外情況時,如何保證穩(wěn)定可靠?

網(wǎng)絡 網(wǎng)絡管理
我們在學習 TCP 建連和斷連時,多數(shù)都在說一個標準的流程,但是網(wǎng)絡環(huán)境是多變的,很多時候并不像教科書那樣標準,那么今天就來聊聊,TCP 三次握手和四次揮手時,如果出現(xiàn)異常情況,是如何處理的?又是由誰來處理?

本文是之前分多篇發(fā)布的文章,現(xiàn)在整理成一篇發(fā)布,調(diào)整了一些小細節(jié)。

一、序

當我們聊到TCP 協(xié)議的時候,聊的最多的就是三次握手與四次揮手。但是大部分資料和文章,寫的都是正常的情況下的流程。但是你有沒有想過,三次握手或者四次揮手時,如果發(fā)生異常了,是如何處理的?又是由誰來處理?

TCP 作為一個靠譜的協(xié)議,在傳輸數(shù)據(jù)的前后,需要在雙端之間建立連接,并在雙端各自維護連接的狀態(tài)。TCP 并沒有什么特別之處,在面對多變的網(wǎng)絡情況,也只能通過不斷的重傳和各種算法來保證可靠性。

建立連接前,TCP 會通過三次握手來保證雙端狀態(tài)正確,然后就可以正常傳輸數(shù)據(jù)了。當數(shù)據(jù)傳輸完成,需要斷開連接的時候,TCP 會通過四次握手來完成雙端的斷連,并回收各自的資源。

我們在學習 TCP 建連和斷連時,多數(shù)都在說一個標準的流程,但是網(wǎng)絡環(huán)境是多變的,很多時候并不像教科書那樣標準,那么今天就來聊聊,TCP 三次握手和四次揮手時,如果出現(xiàn)異常情況,是如何處理的?又是由誰來處理?

二、TCP 三次握手

1. 簡單理解三次握手

雖然是說三次握手的異常情況,我們還是先來了解一下三次握手。

在通過 TCP 傳輸數(shù)據(jù)時,第一步就是要先建立一個連接。TCP 建立連接的過程,就是我們常說的三次握手。

我們經(jīng)常將三次握手,描述成「請求 → 應答 → 應答之應答」。

至于 TCP 握手為什么是三次?其實就是要讓雙端都經(jīng)歷一次「請求 → 應答」的過程,來確認對方還在。網(wǎng)絡情況是多變的,雙端都需要一次自己主動發(fā)起的請求和對方回復的應答過程,來確保對方和網(wǎng)絡是正常的。

下面這張圖,是比較經(jīng)典的 TCP 三次握手的消息和雙端狀態(tài)的變化。

我們先來解釋一下這張圖:

  • 在初始時,雙端處于 CLOSE 狀態(tài),服務端為了提供服務,會主動監(jiān)聽某個端口,進入 LISTEN 狀態(tài)。
  • 客戶端主動發(fā)送連接的「SYN」包,之后進入 SYN-SENT 狀態(tài),服務端在收到客戶端發(fā)來的「SYN」包后,回復「SYN,ACK」包,之后進入 SYN-RCVD 狀態(tài)。
  • 客戶端收到服務端發(fā)來的「SYN,ACK」包后,可以確認對方存在,此時回復「ACK」包,并進入 ESTABLISHED 狀態(tài)。
  • 服務端收到最后一個「ACK」包后,也進入 ESTABLISHED 狀態(tài)。

這是正常的 TCP 三次握手,握手完成后雙端都進入 ESTABLISHED 狀態(tài),在此之后,就是正常的數(shù)據(jù)傳輸過程。

2. TCP 握手的異常情況

三次握手的正常發(fā)包和應答,以及雙端的狀態(tài)扭轉(zhuǎn)我們已經(jīng)講了,接下來就來看看在這三次握手的過程中,出現(xiàn)的異常情況。

(1) 客戶端第一個「SYN」包丟了。

如果客戶端第一個「SYN」包丟了,也就是服務端根本就不知道客戶端曾經(jīng)發(fā)過包,那么處理流程主要在客戶端。

而在 TCP 協(xié)議中,某端的一組「請求-應答」中,在一定時間范圍內(nèi),只要沒有收到應答的「ACK」包,無論是請求包對方?jīng)]有收到,還是對方的應答包自己沒有收到,均認為是丟包了,都會觸發(fā)超時重傳機制。

所以此時會進入重傳「SYN」包。根據(jù)《TCP/IP詳解卷Ⅰ:協(xié)議》中的描述,此時會嘗試三次,間隔時間分別是 5.8s、24s、48s,三次時間大約是 76s 左右,而大多數(shù)伯克利系統(tǒng)將建立一個新連接的最長時間,限制為 75s。

也就是說三次握手第一個「SYN」包丟了,會重傳,總的嘗試時間是 75s。

(2) 服務端收到「SYN」并回復的「SYN,ACK」包丟了。

此時服務端已經(jīng)收到了數(shù)據(jù)包并回復,如果這個回復的「SYN,ACK」包丟了,站在客戶端的角度,會認為是最開始的那個「SYN」丟了,那么就繼續(xù)重傳,就是我們前面說的「錯誤 1」 的流程。

而對服務端而言,如果發(fā)送的「SYN,ACK」包丟了,在超時時間內(nèi)沒有收到客戶端發(fā)來的「ACK」包,也會觸發(fā)重傳,此時服務端處于 SYN_RCVD 狀態(tài),會依次等待 3s、6s、12s 后,重新發(fā)送「SYN,ACK」包。

而這個「SYN,ACK」包的重傳次數(shù),不同的操作系統(tǒng)下有不同的配置,例如在 Linux 下可以通過 tcp_synack_retries 進行配置,默認值為 5。如果這個重試次數(shù)內(nèi),仍未收到「ACK」應答包,那么服務端會自動關(guān)閉這個連接。

同時由于客戶端在沒有收到「SYN,ACK」時,也會進行重傳,當客戶端重傳的「SYN」被收到后,服務端會立即重新發(fā)送「SYN,ACK」包。

(3) 客戶端最后一次回復「SYN,ACK」的「ACK」包丟了。

如果最后一個「ACK」包丟了,服務端因為收不到「ACK」會走重傳機制,而客戶端此時進入 ESTABLISHED 狀態(tài)。

多數(shù)情況下,客戶端進入 ESTABLISHED 狀態(tài)后,則認為連接已建立,會立即發(fā)送數(shù)據(jù)。但是服務端因為沒有收到最后一個「ACK」包,依然處于 SYN-RCVD 狀態(tài)。

那么這里的關(guān)鍵,就在于服務端在處于 SYN-RCVD 狀態(tài)下,收到客戶端的數(shù)據(jù)包后如何處理?

這也是比較有爭議的地方,有些資料里會寫到當服務端處于 SYN-RCVD 狀態(tài)下,收到客戶端的數(shù)據(jù)包后,會直接回復 RTS 包響應,表示服務端錯誤,并進入 CLOSE 狀態(tài)。

但是這樣的設(shè)定有些過于嚴格,試想一下,服務端還在通過三次握手階段確定對方是否真實存在,此時對方的數(shù)據(jù)已經(jīng)發(fā)來了,那肯定是存在的。

所以當服務端處于 SYN-RCVD 狀態(tài)下時,接收到客戶端真實發(fā)送來的數(shù)據(jù)包時,會認為連接已建立,并進入 ESTABLISHED 狀態(tài)。

那么實際情況,為什么會這樣呢?

當客戶端在 ESTABLISHED 狀態(tài)下,開始發(fā)送數(shù)據(jù)包時,會攜帶上一個「ACK」的確認序號,所以哪怕客戶端響應的「ACK」包丟了,服務端在收到這個數(shù)據(jù)包時,能夠通過包內(nèi) ACK 的確認序號,正常進入 ESTABLISHED 狀態(tài)。

(4) 客戶端故意不發(fā)最后一次「SYN」包。

前面一直在說正常的異常邏輯,雙方都還算友善,按規(guī)矩做事,出現(xiàn)異常主要也是因為網(wǎng)絡等客觀問題,接下來說一個惡意的情況。

如果客戶端是惡意的,在發(fā)送「SYN」包后,并收到「SYN,ACK」后就不回復了,那么服務端此時處于一種半連接的狀態(tài),雖然服務端會通過 tcp_synack_retries 配置重試的次數(shù),不會無限等待下去,但是這也是有一個時間周期的。

如果短時間內(nèi)存在大量的這種惡意連接,對服務端來說壓力就會很大,這就是所謂的 SYN FLOOD 攻擊。

這就屬于安全攻防的范疇了,今天就不討論了,有興趣可以自行了解。

三、TCP 四次揮手

1. 簡單理解四次揮手

說完 TCP 三次握手,繼續(xù)來分析 TCP 四次揮手的異常情況。

保持行文風格,在此之前,我們還是先來簡單了解一下 TCP 的四次揮手。

當數(shù)據(jù)傳輸完成,需要斷開連接的時候,TCP 會采取四次揮手的方式,來安全的斷開連接。

為什么握手需要三次,而揮手需要四次呢?

本質(zhì)上來說,雙端都需要經(jīng)過一次「分手」的過程,來保證自己和對端的狀態(tài)正確。本著友好協(xié)商的態(tài)度,你先提出的分手,也要把最大的善意給對方,不能打了對方一個措手不及。你說不玩了就不玩了,那以后誰還敢和你玩。

下面這張圖,是比較經(jīng)典的 TCP 四次揮手的消息和雙端狀態(tài)的變化。

我們解釋一下這張圖:

  • 初始時雙端還都處于 ESTABLISHED 狀態(tài)并傳輸數(shù)據(jù),某端可以主動發(fā)起「FIN」包準備斷開連接,在這里的場景下,是客戶端發(fā)起「FIN」請求。在發(fā)出「FIN」后,客戶端進入 FIN-WAIT-1 狀態(tài)。
  • 服務端收到「FIN」消息后,回復「ACK」表示知道了,并從 ESTABLISHED 狀態(tài)進入 CLOSED-WAIT 狀態(tài),開始做一些斷開連接前的準備工作。
  • 客戶端收到之前「FIN」的回復「ACK」消息后,進入 FIN-WAIT-2 狀態(tài)。而當服務端做好斷開前的準備工作后,也會發(fā)送一個「FIN,ACK」的消息給客戶端,表示我也好了,請求斷開連接,并在發(fā)送消息后,服務端進入 LAST-ACK 狀態(tài)。
  • 客戶端在收到「FIN,ACK」消息后,會立即回復「ACK」,表示知道了,并進入 TIME_WAIT 狀態(tài),為了穩(wěn)定和安全考慮,客戶端會在 TIME-WAIT 狀態(tài)等待 2MSL 的時長,最終進入 CLOSED 狀態(tài)。
  • 服務端收到客戶端回復的「ACK」消息后,直接從 LAST-ACK 狀態(tài)進入 CLOSED 狀態(tài)。

正常的經(jīng)過四次揮手之后,雙端都進入 CLOSED 狀態(tài),在此之后,雙端正式斷開了連接。

2. TCP 揮手的異常情況

四次揮手的正常發(fā)包和應答過程,我們已經(jīng)簡單了解了,接下來就繼續(xù)看看,四次揮手過程中,出現(xiàn)的異常情況。

(1) 斷開連接的 FIN 包丟了。

我們前面一直強調(diào)過,如果一個包發(fā)出去,在一定時間內(nèi),只要沒有收到對端的「ACK」回復,均認為這個包丟了,會觸發(fā)超時重傳機制。而不會關(guān)心到底是自己發(fā)的包丟了,還是對方的「ACK」丟了。

所以在這里,如果客戶端率先發(fā)的「FIN」包丟了,或者沒有收到對端的「ACK」回復,則會觸發(fā)超時重傳,直到觸發(fā)重傳的次數(shù),直接關(guān)閉連接。

對于服務端而言,如果客戶端發(fā)來的「FIN」沒有收到,就沒有任何感知。會在一段時間后,也關(guān)閉連接。

(2) 服務端第一次回復的 ACK 丟了。

此時因為客戶端沒有收到「ACK」應答,會嘗試重傳之前的「FIN」請求,服務端收到后,又會立即再重傳「ACK」。

而此時服務端已經(jīng)進入 CLOSED-WAIT 狀態(tài),開始做斷開連接前的準備工作。當準備好之后,會回復「FIN,ACK」,注意這個消息是攜帶了之前「ACK」的響應序號的。

只要這個消息沒丟,客戶端可以憑借「FIN,ACK」包中的響應序號,直接從 FIN-WAIT-1 狀態(tài),進入 TIME-WAIT 狀態(tài),開始長達 2MSL 的等待。

(3) 服務端發(fā)送的 FIN,ACK 丟了。

服務端在超時后會重傳,此時客戶端有兩種情況,要么處于 FIN-WAIT-2 狀態(tài)(之前的 ACK 也丟了),會一直等待;要么處于 TIME-WAIT 狀態(tài),會等待 2MSL 時間。

也就是說,在一小段時間內(nèi)客戶端還在,客戶端在收到服務端發(fā)來的「FIN,ACK」包后,也會回復一個「ACK」應答,并做好自己的狀態(tài)切換。

(4) 客戶端最后回復的 ACK 丟了。

客戶端在回復「ACK」后,會進入 TIME-WAIT 狀態(tài),開始長達 2MSL 的等待,服務端因為沒有收到「ACK」的回復,會重試一段時間,直到服務端重試超時后主動斷開。

或者等待新的客戶端接入后,收到服務端重試的「FIN」消息后,回復「RST」消息,在收到「RST」消息后,復位服務端的狀態(tài)。

(5) 客戶端收到 ACK 后,服務端跑路了。

客戶端在收到「ACK」后,進入了 FIN-WAIT-2 狀態(tài),等待服務端發(fā)來的「FIN」包,而如果服務端跑路了,這個包永遠都等不到。

在 TCP 協(xié)議中,是沒有對這個狀態(tài)的處理機制的。但是協(xié)議不管,系統(tǒng)來湊,操作系統(tǒng)會接管這個狀態(tài),例如在 Linux 下,就可以通過 tcp_fin_timeout 參數(shù),來對這個狀態(tài)設(shè)定一個超時時間。

需要注意的是,當超過 tcp_fin_timeout 的限制后,狀態(tài)并不是切換到 TIME_WAIT,而是直接進入 CLOSED 狀態(tài)。

(6) 客戶端收到 ACK 后,客戶端自己跑路了。

客戶端收到「ACK」后直接跑路,服務端后續(xù)在發(fā)送的「FIN,ACK」就沒有接收端,也就不會得到回復,會不斷的走 TCP 的超時重試的機制,此時服務端處于 LAST-ACK 狀態(tài)。

那就要分 2 種情況分析:

  • 在超過一定時間后,服務端主動斷開。
  • 收到「RST」后,主動斷開連接。

「RST」消息是一種重置消息,表示當前錯誤了,應該回到初始的狀態(tài)。如果客戶端跑路后有新的客戶端接入,會在此發(fā)送「SYN」以期望建立連接,此時這個「SYN」將被忽略,并直接回復「FIN,ACK」消息,新客戶端在收到「FIN」消息后是不會認的,并且會回復一個「RST」消息。

四、小結(jié)時刻

本文聊了 TCP 在三次握手和四次揮手的時候,出現(xiàn)異常的處理邏輯。

大多數(shù)情況下,都是依賴超時重傳來保證 TCP 的可靠性,但是重傳的次數(shù),狀態(tài)的轉(zhuǎn)換,以及有哪些狀態(tài)是被系統(tǒng)接管,這些細節(jié),就是本文的主題。

 

責任編輯:趙寧寧 來源: 承香墨影
相關(guān)推薦

2015-10-13 09:42:52

TCP網(wǎng)絡協(xié)議

2019-06-12 11:26:37

TCP三次握手四次揮手

2023-10-24 15:22:09

TCPUDP

2024-01-12 08:23:11

TCPACK服務器

2021-07-03 17:47:25

TCP控制協(xié)議

2021-01-29 06:11:08

TCP通信三次握手

2019-02-01 09:38:16

2021-05-18 12:27:40

TCP控制協(xié)議

2020-02-17 10:10:43

TCP三次握手四次揮手

2017-09-25 21:27:07

TCP協(xié)議數(shù)據(jù)鏈

2021-05-28 09:08:20

TCP連接序列號

2020-06-29 14:50:47

TCP狀態(tài)ACK

2015-11-09 09:58:56

2022-11-17 10:20:49

TCP三次握手四次揮手

2023-10-28 09:07:57

TCP面試三次握手

2014-09-19 09:46:46

TCPIP

2023-11-01 08:04:08

WiresharkTCP協(xié)議

2023-10-17 15:44:19

TCP四次揮手

2021-08-04 08:01:28

Linux 三次握手Linux 系統(tǒng)

2020-01-09 09:31:05

三次握手四次揮手 TCP
點贊
收藏

51CTO技術(shù)棧公眾號