議的三次握手與四次揮手詳解)
1. TCP協(xié)議的核心禮儀連接與斷開(kāi)的藝術(shù)在網(wǎng)絡(luò)通信的世界里TCP協(xié)議就像一位彬彬有禮的紳士每一次數(shù)據(jù)交互都遵循著嚴(yán)格的禮儀規(guī)范。這種禮儀不是多余的客套而是確保數(shù)據(jù)可靠傳輸?shù)年P(guān)鍵機(jī)制。想象一下兩位外交官在重要會(huì)談前的正式問(wèn)候——三次握手就像他們確認(rèn)彼此身份和溝通意愿的過(guò)程而四次揮手則如同會(huì)談結(jié)束后禮貌的道別。TCP傳輸控制協(xié)議是互聯(lián)網(wǎng)協(xié)議套件中最核心的傳輸層協(xié)議之一它通過(guò)面向連接、可靠傳輸?shù)奶匦詾樯蠈討?yīng)用提供了穩(wěn)定的數(shù)據(jù)傳輸通道。與UDP的即發(fā)即忘不同TCP要求通信雙方在數(shù)據(jù)傳輸前必須建立連接結(jié)束后必須釋放連接。這種看似繁瑣的機(jī)制實(shí)則是互聯(lián)網(wǎng)可靠通信的基石。提示TCP的可靠性體現(xiàn)在三個(gè)方面——數(shù)據(jù)順序的正確性、數(shù)據(jù)內(nèi)容的完整性以及數(shù)據(jù)傳輸?shù)目蛇_(dá)性。這些特性使得TCP成為HTTP、FTP、SMTP等大多數(shù)互聯(lián)網(wǎng)應(yīng)用的首選傳輸協(xié)議。2. 三次握手建立連接的完美協(xié)奏2.1 握手過(guò)程的詳細(xì)拆解TCP連接的建立需要客戶(hù)端和服務(wù)器之間進(jìn)行三次報(bào)文交換這個(gè)過(guò)程被稱(chēng)為三次握手。讓我們用一個(gè)現(xiàn)實(shí)場(chǎng)景來(lái)類(lèi)比假設(shè)Alice想和Bob建立電話(huà)聯(lián)系第一次握手SYNAlice撥打Bob的電話(huà)并等待接聽(tīng)客戶(hù)端發(fā)送SYN1seqx第二次握手SYNACKBob接聽(tīng)電話(huà)并說(shuō)喂我是Bob服務(wù)器回應(yīng)SYN1ACK1seqyackx1第三次握手ACKAlice回應(yīng)你好Bob我是Alice客戶(hù)端發(fā)送ACK1seqx1acky1在技術(shù)實(shí)現(xiàn)上這三個(gè)步驟對(duì)應(yīng)著TCP報(bào)文頭中特定標(biāo)志位的設(shè)置客戶(hù)端 服務(wù)器 |-------- SYN1, seqx -----------| |-- SYN1, ACK1, seqy, ackx1--| |-------- ACK1, seqx1, acky1-|2.2 為什么是三次而不是兩次這是一個(gè)經(jīng)典的技術(shù)面試題。三次握手的設(shè)計(jì)主要解決了兩個(gè)關(guān)鍵問(wèn)題防止歷史重復(fù)連接的初始化造成的資源浪費(fèi)網(wǎng)絡(luò)中存在延遲的舊SYN報(bào)文可能會(huì)在連接關(guān)閉后到達(dá)服務(wù)器。如果是兩次握手服務(wù)器會(huì)立即建立連接并分配資源而客戶(hù)端知道這是無(wú)效連接不會(huì)響應(yīng)導(dǎo)致服務(wù)器資源浪費(fèi)。確保雙方收發(fā)能力正常第一次握手驗(yàn)證客戶(hù)端發(fā)送能力第二次驗(yàn)證服務(wù)器收發(fā)能力第三次驗(yàn)證客戶(hù)端接收能力。三次交互是最小完備的驗(yàn)證次數(shù)。注意在Linux系統(tǒng)中可以通過(guò)net.ipv4.tcp_syn_retries參數(shù)調(diào)整SYN重試次數(shù)默認(rèn)值通常是5表示在放棄連接前會(huì)進(jìn)行5次SYN重傳嘗試。2.3 握手過(guò)程中的狀態(tài)變遷在三次握手過(guò)程中TCP連接狀態(tài)會(huì)經(jīng)歷一系列變化客戶(hù)端狀態(tài)流CLOSED → SYN_SENT → ESTABLISHED服務(wù)端狀態(tài)流CLOSED → LISTEN → SYN_RCVD → ESTABLISHED使用netstat命令可以查看這些狀態(tài)# 查看TCP連接狀態(tài) netstat -antp # 過(guò)濾處于SYN_RECV狀態(tài)的連接 netstat -antp | grep SYN_RECV3. 四次揮手優(yōu)雅終止連接的四步舞曲3.1 揮手過(guò)程的詳細(xì)解析TCP連接的終止需要四次報(bào)文交換這比建立連接多了一次。繼續(xù)用電話(huà)場(chǎng)景類(lèi)比第一次揮手FINAlice說(shuō)我要說(shuō)的都說(shuō)完了客戶(hù)端發(fā)送FIN1sequ第二次揮手ACKBob回應(yīng)好的我知道了服務(wù)器發(fā)送ACK1acku1第三次揮手FINBob說(shuō)我也說(shuō)完了服務(wù)器發(fā)送FIN1seqv第四次揮手ACKAlice回應(yīng)好的再見(jiàn)客戶(hù)端發(fā)送ACK1ackv1技術(shù)實(shí)現(xiàn)上四次揮手的過(guò)程如下客戶(hù)端 服務(wù)器 |-------- FIN1, sequ -----------| |-------- ACK1, acku1 ---------| |-------- FIN1, seqv -----------| |-------- ACK1, ackv1 ---------|3.2 為什么需要四次揮手TCP是全雙工協(xié)議這意味著數(shù)據(jù)可以同時(shí)在兩個(gè)方向上獨(dú)立傳輸。當(dāng)一方說(shuō)我說(shuō)完了發(fā)送FIN只是表示它不再發(fā)送數(shù)據(jù)但仍然可以接收數(shù)據(jù)。因此前兩次揮手關(guān)閉了客戶(hù)端到服務(wù)器的數(shù)據(jù)通道后兩次揮手關(guān)閉了服務(wù)器到客戶(hù)端的數(shù)據(jù)通道如果服務(wù)器在收到FIN后也沒(méi)有數(shù)據(jù)要發(fā)送可以將第二次和第三次揮手合并變?yōu)槿螕]手。這種情況在HTTP/1.0中比較常見(jiàn)。3.3 TIME_WAIT狀態(tài)的深度解析在第四次揮手后客戶(hù)端會(huì)進(jìn)入TIME_WAIT狀態(tài)等待2MSLMaximum Segment Lifetime報(bào)文最大生存時(shí)間后才完全關(guān)閉連接。這個(gè)設(shè)計(jì)有幾個(gè)重要目的確保最后一個(gè)ACK能到達(dá)服務(wù)器如果丟失服務(wù)器會(huì)重傳FIN讓網(wǎng)絡(luò)中殘留的報(bào)文段自然消亡避免影響后續(xù)相同四元組的新連接在Linux系統(tǒng)中MSL通常設(shè)置為30秒因此TIME_WAIT持續(xù)時(shí)間約為1分鐘# 查看系統(tǒng)TCP參數(shù) cat /proc/sys/net/ipv4/tcp_fin_timeout # 通常為60對(duì)于高并發(fā)服務(wù)器大量TIME_WAIT連接可能導(dǎo)致端口耗盡。可以通過(guò)以下方式優(yōu)化# 啟用TIME_WAIT重用 echo 1 /proc/sys/net/ipv4/tcp_tw_reuse # 快速回收TIME_WAIT連接 echo 1 /proc/sys/net/ipv4/tcp_tw_recycle警告在生產(chǎn)環(huán)境中修改這些參數(shù)需要謹(jǐn)慎評(píng)估不當(dāng)?shù)脑O(shè)置可能導(dǎo)致連接不穩(wěn)定。4. TCP狀態(tài)機(jī)的全景視圖4.1 完整的狀態(tài)轉(zhuǎn)換圖TCP協(xié)議定義了11種狀態(tài)它們之間的轉(zhuǎn)換構(gòu)成了TCP狀態(tài)機(jī)--------- --------- | CLOSED | | LISTEN | --------- --------- | | | 被動(dòng)打開(kāi) | 接收SYN v v --------- 接收SYN ----------- 發(fā)送SYNACK --------- | SYN_SENT|---------------| SYN_RCVD |---------------| LISTEN | --------- ----------- --------- | | | 接收SYNACK | 接收ACK v v ----------- ----------- |ESTABLISHED| |ESTABLISHED| ----------- ----------- | | | 應(yīng)用層關(guān)閉 | 應(yīng)用層關(guān)閉 v v --------- 發(fā)送FIN --------- | FIN_WAIT1|---------------| CLOSE_WAIT| --------- --------- | | | 接收ACK | 發(fā)送FIN v v --------- --------- | FIN_WAIT2| | LAST_ACK| --------- --------- | | | 接收FIN | 接收ACK v v ----------- --------- | TIME_WAIT | | CLOSED | ----------- --------- | | 2MSL超時(shí) v --------- | CLOSED | ---------4.2 關(guān)鍵狀態(tài)解析LISTEN服務(wù)器等待客戶(hù)端SYN的狀態(tài)。通過(guò)netstat -lntp可以查看監(jiān)聽(tīng)狀態(tài)的端口。SYN_RCVD服務(wù)器收到SYN但未完成三次握手的狀態(tài)。大量此狀態(tài)可能遭受SYN Flood攻擊。ESTABLISHED連接已建立數(shù)據(jù)可以正常傳輸。FIN_WAIT1/2主動(dòng)關(guān)閉方等待對(duì)端ACK或FIN的狀態(tài)。CLOSE_WAIT被動(dòng)關(guān)閉方等待應(yīng)用層關(guān)閉的狀態(tài)。大量此狀態(tài)可能應(yīng)用未正確關(guān)閉連接。TIME_WAIT主動(dòng)關(guān)閉方最后的等待狀態(tài)。5. 實(shí)戰(zhàn)使用Wireshark分析握手與揮手5.1 捕獲TCP報(bào)文的基本步驟安裝Wireshark并啟動(dòng)捕獲設(shè)置過(guò)濾條件為tcp.port [目標(biāo)端口]發(fā)起TCP連接如訪問(wèn)網(wǎng)頁(yè)或使用telnet觀察捕獲的TCP報(bào)文序列5.2 三次握手報(bào)文分析示例No. Time Source Destination Protocol Length Info 1 0.000000 192.168.1.100 192.168.1.200 TCP 74 49212 → 80 [SYN] Seq0 Win64240 Len0 2 0.000123 192.168.1.200 192.168.1.100 TCP 74 80 → 49212 [SYN, ACK] Seq0 Ack1 Win65535 Len0 3 0.000150 192.168.1.100 192.168.1.200 TCP 66 49212 → 80 [ACK] Seq1 Ack1 Win64240 Len0關(guān)鍵字段解讀Seq序列號(hào)初始值為隨機(jī)數(shù)ISNAck確認(rèn)號(hào)值為收到的Seq1Win窗口大小表示接收緩沖區(qū)空間Len數(shù)據(jù)長(zhǎng)度握手階段為05.3 四次揮手報(bào)文分析示例No. Time Source Destination Protocol Length Info 1 5.123456 192.168.1.100 192.168.1.200 TCP 66 49212 → 80 [FIN, ACK] Seq101 Ack201 Win64240 Len0 2 5.123579 192.168.1.200 192.168.1.100 TCP 66 80 → 49212 [ACK] Seq201 Ack102 Win65535 Len0 3 5.234567 192.168.1.200 192.168.1.100 TCP 66 80 → 49212 [FIN, ACK] Seq201 Ack102 Win65535 Len0 4 5.234690 192.168.1.100 192.168.1.200 TCP 66 49212 → 80 [ACK] Seq102 Ack202 Win64240 Len0特殊場(chǎng)景分析當(dāng)服務(wù)器沒(méi)有數(shù)據(jù)要發(fā)送時(shí)可能將第二次和第三次揮手合并為[FIN, ACK]如果最后一個(gè)ACK丟失服務(wù)器會(huì)重傳FIN這也是TIME_WAIT存在的意義6. 常見(jiàn)問(wèn)題與性能優(yōu)化6.1 連接建立問(wèn)題排查問(wèn)題現(xiàn)象客戶(hù)端無(wú)法建立TCP連接排查步驟確認(rèn)服務(wù)器是否監(jiān)聽(tīng)正確端口netstat -lntp | grep [port]檢查防火墻規(guī)則iptables -L -n使用telnet測(cè)試連通性telnet [ip] [port]使用tcpdump抓包分析tcpdump -i any port [port] -w capture.pcap常見(jiàn)錯(cuò)誤Connection refused服務(wù)未監(jiān)聽(tīng)或防火墻拒絕Connection timeout網(wǎng)絡(luò)不通或中間設(shè)備攔截No route to host路由問(wèn)題或主機(jī)不可達(dá)6.2 連接關(guān)閉問(wèn)題排查問(wèn)題現(xiàn)象大量CLOSE_WAIT或TIME_WAIT狀態(tài)連接CLOSE_WAIT過(guò)多原因應(yīng)用未正確調(diào)用close()關(guān)閉連接解決檢查應(yīng)用代碼確保資源釋放臨時(shí)方案調(diào)整net.ipv4.tcp_keepalive_time默認(rèn)7200秒TIME_WAIT過(guò)多原因高頻率短連接優(yōu)化方案使用連接池復(fù)用連接啟用tcp_tw_reuse和tcp_tw_recycle調(diào)整net.ipv4.tcp_max_tw_buckets6.3 TCP參數(shù)調(diào)優(yōu)建議# 啟用快速回收TIME_WAIT連接謹(jǐn)慎使用 echo 1 /proc/sys/net/ipv4/tcp_tw_recycle # 允許將TIME_WAIT連接用于新的TCP連接 echo 1 /proc/sys/net/ipv4/tcp_tw_reuse # 增大本地端口范圍 echo 1024 65000 /proc/sys/net/ipv4/ip_local_port_range # 增加最大SYN半連接數(shù) echo 8192 /proc/sys/net/ipv4/tcp_max_syn_backlog # 減少SYNACK重試次數(shù) echo 3 /proc/sys/net/ipv4/tcp_synack_retries7. 高級(jí)話(huà)題TCP協(xié)議擴(kuò)展與變種7.1 TCP Fast Open (TFO)TFO通過(guò)在第一次SYN報(bào)文中攜帶數(shù)據(jù)減少了一次RTT的延遲客戶(hù)端發(fā)送SYNCookie請(qǐng)求服務(wù)端響應(yīng)SYNACKCookie后續(xù)連接可在SYN中攜帶數(shù)據(jù)啟用方法# 查看TFO狀態(tài) cat /proc/sys/net/ipv4/tcp_fastopen # 啟用TFO客戶(hù)端和服務(wù)端功能 echo 3 /proc/sys/net/ipv4/tcp_fastopen7.2 Multipath TCP (MPTCP)MPTCP允許單個(gè)TCP連接使用多個(gè)路徑傳輸數(shù)據(jù)提高可靠性和吞吐量應(yīng)用層透明支持無(wú)縫切換網(wǎng)絡(luò)需要兩端支持檢查內(nèi)核支持cat /proc/sys/net/mptcp/enabled7.3 TCP BBR擁塞控制算法BBR通過(guò)測(cè)量帶寬和RTT來(lái)優(yōu)化發(fā)送速率替代傳統(tǒng)的基于丟包的算法啟用方法# 查看可用擁塞控制算法 sysctl net.ipv4.tcp_available_congestion_control # 設(shè)置BBR算法 echo net.ipv4.tcp_congestion_controlbbr /etc/sysctl.conf sysctl -p8. 協(xié)議安全SYN Flood防御實(shí)踐SYN Flood是一種常見(jiàn)的DDoS攻擊方式攻擊者發(fā)送大量SYN報(bào)文但不完成握手耗盡服務(wù)器資源。防御措施SYN Cookie不立即分配資源通過(guò)Cookie驗(yàn)證合法性echo 1 /proc/sys/net/ipv4/tcp_syncookies減少SYN_RECV超時(shí)echo 3 /proc/sys/net/ipv4/tcp_synack_retries限制SYN速率iptables -A INPUT -p tcp --syn -m limit --limit 1/s -j ACCEPT增大半連接隊(duì)列echo 8192 /proc/sys/net/ipv4/tcp_max_syn_backlog監(jiān)控命令# 查看SYN_RECV狀態(tài)連接數(shù) netstat -antp | grep SYN_RECV | wc -l # 查看半連接隊(duì)列溢出情況 watch -n 1 netstat -s | grep -i listen