經(jīng)典面試題:TCP 三次握手、四次揮手詳解
在網(wǎng)絡(luò)通信的復(fù)雜架構(gòu)里,“三次握手”與“四次揮手”仿若一座無形的橋梁,它們是連接客戶端與服務(wù)器的關(guān)鍵紐帶。這座“橋梁”不僅確保了連接的穩(wěn)固建立,還保障了連接的有序結(jié)束,使得網(wǎng)絡(luò)世界中的信息能夠順暢、準(zhǔn)確地流動。

在面試過程中,TCP 三次握手、四次揮手也經(jīng)常被問到的問題。本文就來快速、詳細的介紹下 TCP 三次握手、四次揮手的全部過程。
TCP 的三次握手和四次揮手實質(zhì)就是 TCP 通信的連接和斷開:
- 三次握手:同步雙方的初始序列號(ISN),確認(rèn)雙方收發(fā)能力正常;
- 四次揮手:雙方獨立關(guān)閉數(shù)據(jù)通道,確保數(shù)據(jù)完整傳輸。
一、TCP頭格式組成
為了使你更好的理解 TCP 三次握手和四次揮手過程,本小節(jié)先介紹下 TCP 頭部格式。

(1) 源端口號和目的端口號:代表連接發(fā)起方和連接接收方
(2) 序號:在建立連接時,由計算機生產(chǎn)的隨機數(shù)作為初始值,通過SYN包傳給接收端主機,每發(fā)送一次數(shù)據(jù),就累加一次該數(shù)據(jù)字節(jié)數(shù)的大小。用來解決網(wǎng)絡(luò)包亂序問題。
(3) 確認(rèn)序號:指下一次期望收到的數(shù)據(jù)的序號,發(fā)送端收到這個確認(rèn)應(yīng)答以后,可以認(rèn)為在這個序號以前的數(shù)據(jù),都已經(jīng)被正常接收。 用來解決網(wǎng)絡(luò)丟包的問題
(4) 標(biāo)志位,如上圖,一共6個
- URG
- ACK:該位為 1 時,「確認(rèn)應(yīng)答」的字段變?yōu)橛行В琓CP 規(guī)定除了最初建立連接時的 SYN 包之外該位必須設(shè)置為 1
- PSH
- RST:該位為 1 時,表示 TCP 連接中出現(xiàn)異常必須強制斷開連接。
- SYN:該位為 1 時,表示希望建立連接,并在其「序列號」的字段進行序列號初始值的設(shè)定。
- FIN:該位為 1 時,表示今后不會再有數(shù)據(jù)發(fā)送,希望斷開連接。當(dāng)通信結(jié)束希望斷開連接時,通信雙方的主機之間就可以相互交換 FIN 位為 1 的 TCP 段。
(5) 數(shù)據(jù):連接需要發(fā)送的內(nèi)容。
二、建立連接:三次握手
三次握手(Three-way Handshake)是 TCP 協(xié)議中用于建立連接的一個重要環(huán)節(jié)。在這一過程中,客戶端和服務(wù)器需要互相發(fā)送三個數(shù)據(jù)包,以確保雙方的接收和發(fā)送能力均正常,并為后續(xù)的數(shù)據(jù)傳輸指定初始化序列號,從而確保數(shù)據(jù)傳輸?shù)目煽啃浴?/p>
TCP 三次握手流程圖如下所示:

圖中字符詳解:
- SYN:代表連接請求或接收的報文段。
- seq:指發(fā)送的第一個字節(jié)的序號。
- ACK:確認(rèn)報文段,用于回應(yīng) SYN。
- ack:確認(rèn)號,表示希望收到的下一個數(shù)據(jù)的第一個字節(jié)的序號。
在 TCP 協(xié)議中,主動發(fā)起連接請求的一方被稱為客戶端,而被動等待連接的一方則被稱為服務(wù)端。無論是客戶端還是服務(wù)端,一旦 TCP 連接成功建立,雙方均可進行數(shù)據(jù)的發(fā)送與接收。
連接建立之初,服務(wù)器和客戶端都處于 CLOSED 狀態(tài)。在通信正式開始前,雙方需要分別創(chuàng)建自己的傳輸控制塊(TCB)。服務(wù)器完成 TCB 創(chuàng)建后,會進入 LISTEN 狀態(tài),隨時準(zhǔn)備接收客戶端發(fā)來的連接請求。
1. 第一次握手
客戶端向服務(wù)端發(fā)送一個 SYN 報文(SYN=1),并指明客戶端的初始化序列號 ISN(x),即圖中的 seq=x,它表示本報文段所發(fā)送的數(shù)據(jù)的第一個字節(jié)的序號。在發(fā)送 SYN 報文后,客戶端進入 SYN_SENT 狀態(tài),意味著它正在等待服務(wù)端的連接確認(rèn)。
SYN_SENT 狀態(tài)解釋:當(dāng)客戶端發(fā)送連接請求后,它進入 SYN_SENT 狀態(tài),等待服務(wù)端的響應(yīng)。在這個狀態(tài)下,客戶端準(zhǔn)備好了接受服務(wù)端的連接確認(rèn)。
TCP 協(xié)議規(guī)定:SYN=1 的報文段是用于建立連接的請求,它不攜帶任何數(shù)據(jù),但會消耗一個序號。這是 TCP 協(xié)議確保連接建立過程中的有序性和可靠性的一種方式。
2. 第二次握手
服務(wù)器在接收到客戶端的 SYN 報文后,會以 SYN 報文作為回應(yīng)(SYN=1),并賦予自己獨特的初始化序列號ISN(y),即圖中的 seq=y。同時,服務(wù)器將客戶端的 ISN+1 設(shè)置為確認(rèn)號 ack 的值,以此確認(rèn)已收到客戶端的 SYN 報文,并期待接收到的下一個數(shù)據(jù)報的起始序號為 x+1。在此之后,服務(wù)器會進入 SYN-RCVD 狀態(tài),等待對連接請求的進一步確認(rèn)。
SYN-RCVD 狀態(tài)解析:當(dāng)服務(wù)器在收到并發(fā)送連接請求后,會進入 SYN-RCVD 狀態(tài),此時它正在等待對初始連接請求的確認(rèn)。在這個狀態(tài)下,服務(wù)器已經(jīng)準(zhǔn)備好接受來自客戶端的進一步通信。
TCP 協(xié)議規(guī)定:SYN=1 且 ACK=1 的報文段是用于確認(rèn)連接的應(yīng)答,它同樣不攜帶任何數(shù)據(jù),但通過確認(rèn)號的使用,確保了連接建立過程中的有序性和可靠性。
3. 第三次握手
在收到服務(wù)器發(fā)送的 SYN 報文后,客戶端會回應(yīng)一個 ACK 報文。這個 ACK 報文將服務(wù)器的 ISN+1 作為 ack 的值,表明客戶端已經(jīng)收到了服務(wù)器的 SYN 報文,并期待接收到的下一個數(shù)據(jù)報的起始序號為 y+1。
同時,客戶端將自己的序列號 seq 設(shè)置為 x+1,即初始序列號 seq=x 增加 1。完成這些操作后,客戶端進入 ESTABLISHED 狀態(tài),表示連接已成功建立。服務(wù)器在收到這個 ACK 報文后,也會轉(zhuǎn)入 ESTABLISHED 狀態(tài),此時雙方連接的建立工作全部完成。
ESTABLISHED 狀態(tài)解釋:當(dāng)一個 TCP 連接進入 ESTABLISHED 狀態(tài)時,它意味著連接已經(jīng)打開,數(shù)據(jù)可以開始在雙方之間傳送。
三、斷開連接:四次揮手
TCP 連接的終止需要經(jīng)過四次包的交換,因此被稱為四次揮手。在這四次交換中,客戶端或服務(wù)器都可以主動發(fā)起連接的釋放動作。值得注意的是,TCP 連接是雙向的,因此四次揮手中,前兩次主要用于斷開一個方向的連接,后兩次則用于斷開另一方向的連接。

1. 第一次揮手
客戶端首先發(fā)送一個 FIN 報文,其中包含一個序列號 seq=u,表示請求連接終止。在發(fā)送完畢后,客戶端停止數(shù)據(jù)發(fā)送,并主動關(guān)閉 TCP 連接。此時,客戶端進入 FIN_WAIT_1 狀態(tài),等待服務(wù)器的確認(rèn)。
FIN_WAIT_1 狀態(tài)解析:該狀態(tài)表示客戶端正在等待遠程 TCP 的連接中斷請求,或者等待先前連接中斷請求的確認(rèn)。FIN=1 標(biāo)志著該報文段是一個連接釋放請求。而 seq=u 則代表客戶端向服務(wù)器發(fā)送的最后一個字節(jié)的序號。
2. 第二次揮手
服務(wù)端在收到客戶端的 FIN 報文后,會發(fā)送一個 ACK 報文作為回應(yīng)。這個 ACK 報文中,序列號值設(shè)為客戶端序號值加 1,意在確認(rèn)已收到客戶端的報文。隨后,服務(wù)端進入 CLOSE_WAIT 狀態(tài),等待本地用戶的連接中斷請求。
CLOSE_WAIT 狀態(tài)解析:在此狀態(tài)下,服務(wù)端等待來自本地用戶的連接釋放請求。ACK 報文中的 ACK=1 表示應(yīng)答,而 seq=v 則指明了服務(wù)端釋放應(yīng)答報文段的首字節(jié)序號。同時,ack=u+1 表明服務(wù)端希望從第 u+1 個字節(jié)開始接收報文段,并已成功接收了前 u 個字節(jié)。
完成第二次揮手后,客戶端到服務(wù)端的連接已釋放,服務(wù)端不再接收客戶端數(shù)據(jù),而客戶端也已無數(shù)據(jù)待發(fā)送。然而,服務(wù)端到客戶端的連接仍保持開啟,若服務(wù)端在此期間發(fā)送數(shù)據(jù),客戶端仍需正常接收。此狀態(tài)將持續(xù)一段時間,直至整個 CLOSE-WAIT 狀態(tài)結(jié)束。
3. 第三次揮手
服務(wù)端在完成數(shù)據(jù)的發(fā)送后,會向客戶端發(fā)送一個連接釋放報文。這個報文頭包含 FIN 標(biāo)志位為 1,以及 ack 序號值為 u+1。由于在 CLOSE_WAIT 狀態(tài)期間,服務(wù)端可能又發(fā)送了一些數(shù)據(jù),假設(shè)此時的序列號為 seq=w。發(fā)送完畢后,服務(wù)端進入 LAST_ACK 狀態(tài),等待來自客戶端的連接中斷確認(rèn)。
4. 第四次揮手
客戶端在收到服務(wù)端的 FIN 報文后,會響應(yīng)一個 ACK 報文,其中 ack 序號值為 w+1,同時將自己的序列值加 1作為 ACK 報文的 seq 序號值,即 seq=u+1。此后,客戶端進入 TIME_WAIT 狀態(tài)。
TIME_WAIT:確保遠程 TCP 收到連接中斷請求的確認(rèn)狀態(tài)會持續(xù) 2MSL(最長報文段壽命)的時間。在此期間, TCP 連接并未完全釋放。若在這段時間內(nèi)未收到服務(wù)端的重發(fā)請求,客戶端將進入 CLOSED 狀態(tài),并撤銷 TCB。
服務(wù)端在收到客戶端的確認(rèn) ACK 報文后,會立即進入 CLOSED 狀態(tài),并撤銷 TCB,從而結(jié)束此次 TCP 連接。值得注意的是,服務(wù)端結(jié)束 TCP 連接的時間點通常早于客戶端。
四、四次揮手 vs 三次握手
階段 | 三次握手 | 四次揮手 |
目的 | 建立連接,同步序列號 | 安全關(guān)閉雙向數(shù)據(jù)通道 |
交互次數(shù) | 3次 | 4次 |
關(guān)鍵標(biāo)志位 | SYN 、ACK | FIN 、ACK |
狀態(tài)復(fù)雜度 | 簡單(直接建立) | 復(fù)雜(需處理半關(guān)閉和TIME_WAIT) |
五、關(guān)聯(lián)面試題
1. 為何 TCP 建立連接時采用三次握手而非兩次或四次?
- 兩次不夠:無法確認(rèn)客戶端的接收能力(若服務(wù)端的SYN-ACK丟失,客戶端不知服務(wù)端已就緒)。
- 四次冗余:三次已能確保雙向通信能力,無需額外交互。
具體原因如下:
- 確保雙方都能發(fā)送和接收:三次握手可以確保雙方都具備發(fā)送和接收數(shù)據(jù)的能力。在第一次握手時,客戶端發(fā)起請求,第二次握手時,服務(wù)器確認(rèn)收到了請求并表示自己也可以通信,第三次握手時,客戶端確認(rèn)收到了服務(wù)器的響應(yīng)。這保證了通信的可靠性。
- 防止重復(fù)連接初始化問題:假設(shè)沒有三次握手,而是兩次握手,那么可能會出現(xiàn)一種情況:客戶端發(fā)送了一個連接請求(SYN),但由于網(wǎng)絡(luò)問題,服務(wù)器沒有及時收到或者延遲了。客戶端在等待了一段時間后認(rèn)為請求失敗,重新發(fā)送了一個新的 SYN,而此時第一個 SYN 報文延遲到達服務(wù)器,服務(wù)器誤認(rèn)為客戶端又發(fā)起了一次新的連接請求,從而產(chǎn)生混亂。通過三次握手,能夠有效避免這種問題,確保連接的一致性。
- 同步初始序列號:三次握手過程中,客戶端和服務(wù)器會相互交換各自的初始序列號,以保證接下來的數(shù)據(jù)傳輸能夠按順序接收和處理。這是實現(xiàn)TCP可靠傳輸?shù)年P(guān)鍵步驟之一。
三次握手的設(shè)計主要是為了確保在不可靠的網(wǎng)絡(luò)環(huán)境中,TCP連接的建立過程能夠具有可靠性和一致性,并能夠防止?jié)撛诘腻e誤連接。
2. 為何 TCP 關(guān)閉連接時需要四次揮手?
- 保證雙方數(shù)據(jù)完整性:在關(guān)閉連接之前,雙方需要確認(rèn)所有數(shù)據(jù)已經(jīng)被成功接收。第一次揮手時,客戶端發(fā)送 FIN 報文,表示自己不再發(fā)送數(shù)據(jù),但仍然可以接收數(shù)據(jù)。第二次揮手時,服務(wù)器確認(rèn)收到這個 FIN,并且可以繼續(xù)發(fā)送數(shù)據(jù)。第三次揮手時,服務(wù)器發(fā)送自己的 FIN 報文,表示自己也不再發(fā)送數(shù)據(jù)。最后,客戶端確認(rèn)服務(wù)器的 FIN,確保雙方都完成了數(shù)據(jù)傳輸。
- 分半關(guān)閉(Half-Close):TCP 連接是全雙工的,這意味著數(shù)據(jù)可以雙向流動。四次揮手允許連接的一方關(guān)閉數(shù)據(jù)發(fā)送通道,但仍然可以接收數(shù)據(jù),直到另一方也關(guān)閉發(fā)送通道。因此,四次揮手過程允許雙向關(guān)閉連接,確保雙方都能完成數(shù)據(jù)傳輸。
- 確保完整關(guān)閉:客戶端在進入TIME-WAIT狀態(tài)后,會等待一段時間以確保服務(wù)器收到了最后的 ACK 報文。這段時間可以避免因網(wǎng)絡(luò)延遲等問題導(dǎo)致的重復(fù)數(shù)據(jù)問題,確保連接完全關(guān)閉后再釋放資源。
3. 為何 TIME_WAIT 狀態(tài)需持續(xù) 2MSL 后才能轉(zhuǎn)為 CLOSE 狀態(tài)?
當(dāng) TCP 連接的一方完成連接釋放后,會進入 TIME_WAIT 狀態(tài)。這個狀態(tài)需要持續(xù) 2 倍的最大段壽命(Maximum Segment Lifetime,MSL)的時間,這是為了確保在傳輸過程中可能存在的延遲數(shù)據(jù)包能夠被對方完全接收。只有當(dāng) 2MSL 時間過去后,確認(rèn)對方已收到所有數(shù)據(jù),該 TCP 連接才能完全關(guān)閉,進 入CLOSE 狀態(tài)。
(1) 確保服務(wù)端能夠接收到客戶端的確認(rèn)應(yīng)答。
如果客戶端在發(fā)送完確認(rèn)應(yīng)答后立即進入 CLOSED 狀態(tài),而該應(yīng)答不幸丟失,服務(wù)端在等待超時后將嘗試重新發(fā)送連接釋放請求。但此時,由于客戶端已經(jīng)關(guān)閉,無法再作出響應(yīng),這會導(dǎo)致服務(wù)端無法正常關(guān)閉 TCP 連接。因此,TIME_WAIT 狀態(tài)的持續(xù)存在,是為了保證服務(wù)端能夠接收到并處理客戶端的確認(rèn)應(yīng)答,從而確保連接的平滑關(guān)閉。
(2) 防止“三次握手”中提及的“已失效的連接請求報文段”干擾當(dāng)前連接。
當(dāng)客戶端發(fā)送完最后一個確認(rèn)報文后,經(jīng)過 2MSL 的時間間隔,可以確保在本連接持續(xù)時間內(nèi)產(chǎn)生的所有報文段都已從網(wǎng)絡(luò)中清除。這樣,新建立的連接就不會受到舊連接請求報文的影響。
(3) 為什么是 2MSL?
2MSL 的時間是從客戶端收到 FIN 報文段后發(fā)送給服務(wù)器 ACK 開始計時的,考慮到重傳的因素,那么就需要服務(wù)器再次給客戶端傳 FIN+ACK 報文段。
保證在兩個傳輸方向上的尚未被接收或遲到的報文段都消失,理論上保證最后一個報文可靠到達,就需要 2MSL,一個方向一個 1MSL。
4. CLOSE_WAIT 狀態(tài)有什么影響?
當(dāng)服務(wù)器收到客戶端的 FIN,并回復(fù)了 ACK 后,會進入 CLOSE_WAIT 狀態(tài),此時 TCP 鏈接處于半關(guān)閉狀態(tài)。CLOSE_WAIT 狀態(tài)一直存在就說明服務(wù)器沒有調(diào)用 close 并沒有發(fā)送 FIN 報文段。而服務(wù)期長期保持這個狀態(tài),就會一直占用這大量的 socket 文件描述符,大量的 CLOSE_WAIT 狀態(tài)存在就會導(dǎo)致文件描述符被占用,一些客戶端無法連接。
5. TIME_WAIT和CLOSE_WAIT的區(qū)別?
CLOSE_WAIT 狀態(tài)是被動關(guān)閉的一端在接收到另一端關(guān)閉請求過后并將 ACK 發(fā)送出去后所處的狀態(tài)。這種狀態(tài)表示:收到了對端關(guān)閉的情況,但是本端還沒有完成工作,未關(guān)閉。
TIME_WAIT 狀態(tài)是主動關(guān)閉一端在本端已經(jīng)關(guān)閉的前提下,收到對端的關(guān)閉請求并且將 ACK 發(fā)送出去所處的狀態(tài)。這種狀態(tài)表示:雙方都已經(jīng)完成工作,只是為了確保遲來的數(shù)據(jù)報能被識別丟棄,可靠的終止 TCP 連接。
6. 為什么連接的時候是三次握手,關(guān)閉的時候卻是四次揮手?
因為當(dāng)服務(wù)端收到客戶端的 SYN 連接請求報文后,可以直接發(fā)送 SYN+ACK 報文。其中 ACK 報文是用來應(yīng)答的,SYN 報文是用來同步的。
但是關(guān)閉連接時,當(dāng)服務(wù)端收到 FIN 報文時,很可能并不會立即關(guān)閉 SOCKET,所以只能先回復(fù)一個 ACK 報文,告訴客戶端,“你發(fā)的 FIN 報文我收到了”。只有等到我服務(wù)端所有的報文都發(fā)送完了,我才能發(fā)送 FIN 報文,因此不能一起發(fā)送。故需要四步握手。
7. 如果已經(jīng)建立了連接,但是客戶端突然出現(xiàn)故障了怎么辦?
TCP 設(shè)有一個?;钣嫊r器,顯然,客戶端如果出現(xiàn)故障,服務(wù)器不能一直等下去,白白浪費資源。服務(wù)器每收到一次客戶端的請求后都會重新復(fù)位這個計時器,時間通常是設(shè)置為 2 小時,若 2 小時還沒有收到客戶端的任何數(shù)據(jù),服務(wù)器就會發(fā)送一個探測報文段,以后每隔 75 分鐘發(fā)送一次。若一連發(fā)送 10 個探測報文仍然沒反應(yīng),服務(wù)器就認(rèn)為客戶端出了故障,接著就關(guān)閉連接。
8. 在三次握手中,SYN 和 ACK 的作用是什么?
在 TCP 的三次握手中,SYN 和 ACK 確保了連接的建立和通信的同步。
- SYN(Synchronize)是 TCP 協(xié)議中的一個標(biāo)志位,用于在建立連接時進行通信的同步。在三次握手的第一次交互中,客戶端發(fā)送一個 SYN=1,ACK=0 標(biāo)志的數(shù)據(jù)包給服務(wù)端,請求建立連接。這個 SYN 包的作用是向服務(wù)端發(fā)起連接請求,并附帶一個序列號(Sequence Number),用于標(biāo)識后續(xù)發(fā)送的數(shù)據(jù)包。SYN 標(biāo)志位的設(shè)置表示客戶端希望建立一個新的連接或確認(rèn)一個連接請求;
- ACK(Acknowledgement)是確認(rèn)標(biāo)志,用于確認(rèn)接收到的數(shù)據(jù)包。在第二次握手中,服務(wù)端收到客戶端的 SYN 包后,會發(fā)送一個 SYN=1,ACK=1 標(biāo)志的數(shù)據(jù)包給客戶端。這個 SYN+ACK 包的作用是告訴客戶端,服務(wù)端已經(jīng)收到了連接請求,并允許建立連接。同時,ACK=1 表示服務(wù)端對客戶端發(fā)送的 SYN 包進行了確認(rèn)。此外,服務(wù)端也會發(fā)送自己的序列號給客戶端,用于后續(xù)的數(shù)據(jù)傳輸。
- 在第三次握手中,客戶端收到服務(wù)端的 SYN+ACK 包后,會發(fā)送一個 SYN=0,ACK=1 的數(shù)據(jù)包給服務(wù)端。這個 ACK 包的作用是告訴服務(wù)端,客戶端已經(jīng)收到了 SYN+ACK 包,并對服務(wù)端的 SYN 包進行了確認(rèn)。
- 至此,三次握手完成,TCP 連接建立成功,雙方可以開始進行數(shù)據(jù)傳輸。
在整個過程中,SYN 和 ACK 標(biāo)志位確保了連接的建立和通信的同步。SYN 用于發(fā)起連接請求和標(biāo)識序列號,而ACK 用于確認(rèn)接收到的數(shù)據(jù)包。這種機制可以有效地確保數(shù)據(jù)的可靠傳輸和連接的穩(wěn)定性。
9. 三次握手過程中可以攜帶數(shù)據(jù)嗎?
在 TCP 的三次握手過程中,SYN 和 SYN+ACK 報文段是不攜帶數(shù)據(jù)的,它們僅僅用于建立連接時的同步和確認(rèn)。但是,最后一次的 ACK 報文段是可以攜帶數(shù)據(jù)的。這是因為當(dāng)發(fā)送方收到對方的 SYN+ACK 報文段后,連接就已經(jīng)建立了,此時發(fā)送方就可以立即發(fā)送數(shù)據(jù),而這個數(shù)據(jù)就可以和 ACK 報文段一起發(fā)送,從而提高了效率。
雖然第三次握手可以攜帶數(shù)據(jù),但在實際網(wǎng)絡(luò)編程中,并不推薦這樣做。因為這樣做可能會帶來一些問題,比如接收方可能無法及時準(zhǔn)備好接收數(shù)據(jù),導(dǎo)致數(shù)據(jù)丟失或亂序。
因此,通常建議將數(shù)據(jù)的發(fā)送放在三次握手完成之后進行,以確保數(shù)據(jù)的可靠傳輸。
10. TCP 連接中的半連接隊列和全連接隊列是什么?
TCP 連接中的半連接隊列(也稱為 SYN 隊列)用于存儲處于 TCP 三次握手過程中第一步的連接請求。
當(dāng)服務(wù)端收到客戶端發(fā)起的 SYN 請求后,內(nèi)核會把該連接存儲到半連接隊列中,等待完成三次握手的過程。此時,連接請求還沒有完成握手,因此被認(rèn)為是“半連接”。如果半連接隊列滿了,新來的連接請求可能會被丟棄或者根據(jù)系統(tǒng)配置發(fā)送 RST 報文。
全連接隊列就是已經(jīng)完成三次握手,建立起連接的就會放在全連接隊列中。
半連接隊列的主要作用是管理并跟蹤那些尚未完全建立的連接,確保在三次握手完成之前,這些連接請求能夠得到妥善的處理。它是 TCP 協(xié)議保證連接可靠性和性能的重要機制之一。
需要注意的是,當(dāng)服務(wù)端并發(fā)處理大量請求時,如果 TCP 半連接隊列過小,就容易出現(xiàn)溢出的情況,導(dǎo)致后續(xù)的請求被丟棄,從而影響服務(wù)端的請求處理能力。因此,合理設(shè)置和調(diào)整半連接隊列的大小對于優(yōu)化網(wǎng)絡(luò)性能和提升系統(tǒng)穩(wěn)定性具有重要意義。
11. TCP 連接中 ISN(Initial Sequence Number)是什么?
在 TCP 連接中,ISN(Initial Sequence Number,初始序列號)是每個 TCP 連接在建立時由 TCP 協(xié)議為每一個數(shù)據(jù)包所賦予的序列號。它是 TCP 可靠傳輸?shù)囊粋€重要組成部分,用于確保數(shù)據(jù)的順序性和完整性。
- 當(dāng) TCP 連接建立時,客戶端和服務(wù)器都會選擇一個初始序列號(ISN)作為它們發(fā)送的第一個數(shù)據(jù)包的序列號。這個序列號是一個隨機值,通常不會重復(fù),用于標(biāo)識該連接中的每一個數(shù)據(jù)包的順序。
- 在數(shù)據(jù)傳輸過程中,TCP 協(xié)議會根據(jù)數(shù)據(jù)包的發(fā)送順序為每個數(shù)據(jù)包分配一個遞增的序列號。ISN 可以看作是一個 32 比特的計數(shù)器,每 4ms 加 1 。
- 通過序列號,接收方可以準(zhǔn)確地按照發(fā)送方的發(fā)送順序來重組數(shù)據(jù),從而確保數(shù)據(jù)的順序性。
- 此外,序列號還可以用于檢測丟失或重復(fù)的數(shù)據(jù)包。當(dāng)接收方發(fā)現(xiàn)數(shù)據(jù)包的序列號不連續(xù)時,它會向發(fā)送方發(fā)送一個 ACK(確認(rèn))消息,請求發(fā)送方重傳丟失的數(shù)據(jù)包。同樣地,如果接收方接收到一個重復(fù)的數(shù)據(jù)包(即具有相同序列號的數(shù)據(jù)包),它可以通過序列號來識別并丟棄這個重復(fù)的數(shù)據(jù)包。
因此,ISN 在 TCP 連接確保了數(shù)據(jù)的順序性和完整性,為 TCP 的可靠傳輸提供了基礎(chǔ)。
12. 為什么 TCP 連接建立需要發(fā)送序列號?
TCP 連接建立需要發(fā)送序列號的原因主要有以下幾點:
- 確保數(shù)據(jù)的順序性: TCP 是一個面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議。在 TCP 通信中,發(fā)送方和接收方都需要按照數(shù)據(jù)的發(fā)送順序來接收和處理數(shù)據(jù)。序列號用于標(biāo)識每一個發(fā)送的數(shù)據(jù)包,確保接收方能夠按照正確的順序重組數(shù)據(jù)。
- 實現(xiàn)可靠傳輸: TCP 通過序列號來實現(xiàn)數(shù)據(jù)的可靠傳輸。當(dāng)接收方收到數(shù)據(jù)包后,會向發(fā)送方發(fā)送一個確認(rèn)(ACK)消息,告知已經(jīng)成功接收到的數(shù)據(jù)包的序列號。如果發(fā)送方在某個時間點內(nèi)沒有收到某個數(shù)據(jù)包的 ACK,它會認(rèn)為該數(shù)據(jù)包丟失,并重新發(fā)送該數(shù)據(jù)包。序列號使得發(fā)送方能夠準(zhǔn)確地知道哪些數(shù)據(jù)包已經(jīng)成功發(fā)送并被接收,哪些數(shù)據(jù)包需要重傳。
- 處理網(wǎng)絡(luò)中的數(shù)據(jù)包亂序: 在網(wǎng)絡(luò)傳輸過程中,由于網(wǎng)絡(luò)擁塞、路由變化等原因,數(shù)據(jù)包可能會亂序到達接收方。通過序列號,接收方能夠識別并重新排序這些亂序的數(shù)據(jù)包,確保數(shù)據(jù)的完整性和正確性。
- 流量控制和擁塞控制: TCP 還利用序列號來實現(xiàn)流量控制和擁塞控制。發(fā)送方會根據(jù)接收方的確認(rèn)消息和當(dāng)前的網(wǎng)絡(luò)狀況來調(diào)整發(fā)送速率,以避免網(wǎng)絡(luò)擁塞和數(shù)據(jù)丟失。序列號在這個過程中起到了關(guān)鍵作用,幫助發(fā)送方和接收方協(xié)調(diào)數(shù)據(jù)的發(fā)送和接收。
TCP 連接建立需要發(fā)送序列號是為了確保數(shù)據(jù)的順序性、實現(xiàn)可靠傳輸、處理網(wǎng)絡(luò)中的數(shù)據(jù)包亂序以及實現(xiàn)流量控制和擁塞控制。這些功能共同保證了 TCP 能夠提供高效、可靠的數(shù)據(jù)傳輸服務(wù)。
13. 在 TCP 通信中,如果一方突然崩潰,另一方如何知道?
在 TCP 通信中,如果一方突然崩潰(例如,由于硬件故障、操作系統(tǒng)崩潰或應(yīng)用程序異常終止),另一方通常通過以下幾種機制來檢測這種情況:
- 心跳機制(Keep-Alive): TCP 本身并沒有一個顯式的“心跳”機制,但許多操作系統(tǒng)和應(yīng)用程序?qū)訁f(xié)議實現(xiàn)了這種機制。通過定期發(fā)送小的數(shù)據(jù)包(通常稱為“探測包”或“心跳包”),接收方可以通知發(fā)送方它仍然存活并且連接仍然有效。如果發(fā)送方在一段時間內(nèi)沒有收到響應(yīng),它可能會認(rèn)為接收方已經(jīng)崩潰,并關(guān)閉連接。
- 超時重傳和重試: TCP 使用超時重傳機制來處理丟失的數(shù)據(jù)包。當(dāng)發(fā)送方發(fā)送一個數(shù)據(jù)包后,它會等待一個確認(rèn)(ACK)。如果在一定的超時時間內(nèi)沒有收到 ACK,發(fā)送方會重傳該數(shù)據(jù)包。如果經(jīng)過多次重傳仍然未收到確認(rèn),發(fā)送方會認(rèn)為連接已經(jīng)中斷,并關(guān)閉連接。同樣,接收方在收到亂序的數(shù)據(jù)包或數(shù)據(jù)包丟失時,也會通過發(fā)送重復(fù) ACK 或通知發(fā)送方進行快速重傳來處理。
- 應(yīng)用層協(xié)議: 除了 TCP 本身的機制外,應(yīng)用層協(xié)議(如 HTTP、FTP 等)通常也會實現(xiàn)自己的連接管理和錯誤處理機制。這些協(xié)議可能會定義特定的消息或命令來通知對方連接已經(jīng)中斷,或者通過超時和重試策略來處理突然的崩潰。
- 操作系統(tǒng)和網(wǎng)絡(luò)棧的通知: 在某些情況下,當(dāng)一方崩潰時,操作系統(tǒng)或網(wǎng)絡(luò)??赡軙蛄硪环桨l(fā)送一個特殊的信號或錯誤消息。例如,當(dāng) TCP 連接的一方異常終止時,操作系統(tǒng)可能會向另一方發(fā)送一個 RST(重置)數(shù)據(jù)包來關(guān)閉連接。
由于網(wǎng)絡(luò)的復(fù)雜性和不確定性,有時候即使一方崩潰,另一方也可能無法立即檢測到。這取決于網(wǎng)絡(luò)狀況、操作系統(tǒng)的實現(xiàn)以及應(yīng)用層協(xié)議的設(shè)計。因此,在設(shè)計和實現(xiàn)基于 TCP 的應(yīng)用程序時,應(yīng)該考慮到這種可能性,并采取相應(yīng)的錯誤處理和恢復(fù)策略。




























