成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么 TCP 需要 TIME_WAIT,你知道嗎 ?

網絡
當我們在本地 (客戶端) 啟動并發壓力測試時,通常會設置成百上千的并發連接去訪問服務端接口,這些連接會快速且大量消耗 TCP 連接資源,每個連接在完成接口請求后會理解進入 TIME_WAIT 狀態。

TCP 狀態機

下圖所示的狀態機展示了,通信雙方建立 TCP 連接之后的狀態轉換過程。

圖片來源: tcpipguide.com

通信雙方主動發起關閉連接的一端,存在 TIME_WAIT 狀態,被動接受關閉連接的一端,會進入 CLOSE_WAIT 狀態。

處于 TIME_WAIT 狀態的一端,主要浪費兩種資源:

  • 端口號 (主要資源)
  • 系統資源 (文件描述符、內存資源、CPU 資源、線程資源),對于現代化硬件來說,這點資源可以忽略不計

兩個問題

這里以客戶端主動關閉連接為例,先來看下經典的 “四次揮手” 過程:

圖片來源: tcpipguide.com

  • 第一次揮手: 當客戶端沒有要發送的數據時,向服務端發送 FIN 消息,客戶端進入 FIN_WAIT_1 狀態
  • 第二次揮手: 服務端收到客戶端的 FIN 消息之后,進入 CLOSE_WAIT 狀態,然后向客戶端發送 ACK 消息,客戶端收到 ACK 消息之后進入 FIN_WAIT_2 狀態
  • 第三次揮手: 當服務端沒有要發送的數據時,向客戶端發送 FIN 消息,然后服務端進入 LAST_ACK 狀態
  • 第四次揮手: 客戶端收到服務端的 FIN 消息之后,進入 TIME_WAIT 狀態,然后向服務端發送 ACK 消息,服務端收到 ACK 消息進入 CLOSED 狀態
  • 客戶端等大等待 2 個 MSL 時間后進入 CLOSED 狀態

客戶端需要維護一個 TIME_WAIT 狀態長達 2 個 MSL 時間,以 Linux 5.0 代碼為例,也就是 2 分鐘。

// https://github.com/torvalds/linux/blob/1c163f4c7b3f621efff9b28a47abb36f7378d783/include/net/tcp.h#L121

#define TCP_TIMEWAIT_LEN (60*HZ) /* how long to wait to destroy TIME-WAIT state, about 60 seconds */

為什么是 2 個 MSL 時間呢?

因為發送方要考慮數據報文 從發送方到接收方的 MSL, 反過來說,接收方也要考慮 ACK 報文從接收方到發送方的 MSL,所以一共是 2 個 MSL (通信雙方各一個)。

之所以采用這種機制,主要是為了避免發生下面兩個問題:

  • 防止被動關閉連接的一端,延遲的數據被后續使用 相同四元組的 TCP 連接 接收
  • 防止被動關閉連接的一端,發出的 FIN 消息沒有收到對應的 ACK 消息,而在新連接到來的時候發送 RST 消息

下面就這兩個問題來進行分析說明。

第一個問題

防止被動關閉連接的一端,延遲的數據被后續使用 相同四元組的新連接 接收。

簡單來說,就是防止舊的 TCP 連接,因為延遲到達的報文,而干擾到了復用相同四元組的新連接。

四元組客戶端客戶端端口服務端服務端端口

下面來舉例說一下什么場景下會出現這種情況。

延遲到達的報文干擾到了新連接

  • 假設在客戶端在主動關閉連接前,服務端發送了一個 seq = 1001 的數據包 A,但是由于網絡原因一直沒有送達到客戶端 (也就是以說,該數據包延遲了)
  • 如果客戶端沒有 TIME_WAIT 狀態,那么客戶端第四次揮手后,此時客戶端會直接進入 CLOSED 狀態
  • 延遲的數據包 A 依然沒有到來
  • 這時客戶端又向服務端發起新的連接,很巧的是,這個新連接和剛才 (已關閉) 的舊連接使用了同樣的端口 (復用),于是新連接和舊連接的四元組變成了一樣的
  • 新連接建立完成后,舊連接上面的延遲數據包 A 到了 (新連接),這時就會產生嚴重的問題 ...

通過 TIME_WAIT 狀態,發起主動關閉連接的一端會等待 2 個 MSL 時間,這個時間足夠長,可以最大限度消除延遲的數據包可能對新 (復用端口) 的連接造成影響, TIME_WAIT 狀態下接收到的延遲數據包會被直接丟棄。

這里考慮一個極端的 (小概率) 問題: 經過 2 個 MSL 時間之后,延遲的數據包 A 到達了,并且其 Seq 正好位于新連接的接收窗口內,那么新連接 (TCP 傳輸層) 會直接將整個數據包轉交到上層應用嗎?

根據應用層安全 (是否加密) 程度,分為兩種情況:

  • 未加密,那么就會干擾應用數據,例如源數據為 “我的頭像牛 X 嗎?”,因為延遲的數據包,在 頭 字后面插入了一個逗號,變成了 “我的頭,像牛 X 嗎?”
  • 已加密 (例如使用了 HTTPS),TLS 會校驗數據完整性,那么顯然數據包 A 是無法通過校驗的,然后被直接丟棄,HTTPS 連接就此中斷

第二個問題

防止被動關閉連接的一端,發出的 FIN 消息沒有收到對應的 ACK 消息,而在新連接到來的時候發送 RST 消息。

簡單來說,就是防止舊的 TCP 連接在第四次揮手中發出的 ACK 消息沒有被對端收到,而導致復用相同四元組的新連接在和對端建立連接時被拒絕。

下面來舉例說一下什么場景下會出現這種情況。

新連接建立時被 RST 消息拒絕

  • 客戶端第四次揮手時向服務端發送 ACK 消息,但是這個 ACK 消息一直因為網絡原因一直未送達,所以服務端的狀態停留在了 LAST-ACK,而不是正常的 CLOSED 狀態
  • 如果客戶端沒有 TIME_WAIT 狀態,那么客戶端第四次揮手后,此時客戶端會直接進入 CLOSED 狀態,但是此時服務端認為這條連接依然是有效的 (還未徹底斷開)
  • 這時客戶端又向服務端發起新的連接,很巧的是,這個新連接和剛才 (已關閉) 的舊連接使用了同樣的端口 (復用),于是新連接和舊連接的四元組變成了一樣的
  • 服務端收到了客戶端的新鏈接建立時發送的 SYNC 消息,在服務端看來,這其實是一條舊的有效連接 (因為新連接和舊連接的四元組是一樣的),所以會直接返回 RST 消息,拒絕新連接的建立 (連接過程到此終止)

通過 TIME_WAIT 狀態,發起主動關閉連接的一端會等待 2 個 MSL 時間,這個時間足夠長,那么服務端可能會出現兩種情況:

  • 收到了客戶端的 ACK 消息,正常關閉連接,進入 CLOSE 狀態
  • 沒有收到客戶端的 ACK 消息,重新發送 FIN 消息關閉連接并等待新的 ACK 消息 (重新執行第三次、四次揮手)

問題場景

分析完了 TIME_WAIT 狀態的作用之外,什么場景下會出現大量的 TIME_WAIT 狀態連接呢?

通信雙方主動發起關閉連接的一端,存在 TIME_WAIT 狀態,最經典的場景就是 并發壓力測試。

當我們在本地 (客戶端) 啟動并發壓力測試時,通常會設置成百上千的并發連接去訪問服務端接口,這些連接會快速且大量消耗 TCP 連接資源,每個連接在完成接口請求后會理解進入 TIME_WAIT 狀態。

例如,在 Linux 系統中,可以使用 netstat 命令來查看各個不同狀態的網絡連接:

$ netstat -ant | grep TIME_WAIT

# 輸出如下
tcp6       0      0 1.1.1.1:443          127.0.0.1:59490         TIME_WAIT
tcp6       0      0 1.1.1.1:443          127.0.0.1:59472         TIME_WAIT
tcp6       0      0 1.1.1.1:443          127.0.0.1:59480         TIME_WAIT
tcp6       0      0 1.1.1.1:443          127.0.0.1:59514         TIME_WAIT
tcp6       0      0 1.1.1.1:443          127.0.0.1:59484         TIME_WAIT
tcp6       0      0 1.1.1.1:443          127.0.0.1:59520         TIME_WAIT

這類問題如何解決,后面再專門寫一篇高性能網絡編程中 TCP 調優的文章 :-)。

? 思考

如果系統中出現大量的 CLOSE_WAIT 狀態連接,可能原因是什么呢?如何解決?

責任編輯:趙寧寧 來源: 洋芋編程
相關推薦

2020-11-17 08:30:06

LinuxSwapping 設計

2025-06-05 01:11:00

2023-11-02 10:22:29

gRPC后端通信

2024-10-09 08:19:35

2017-10-16 13:45:04

2015-03-27 10:18:25

TCP協議CLOSE_WAIT狀服務器異常

2023-12-20 08:23:53

NIO組件非阻塞

2024-04-30 09:02:48

2020-08-06 10:12:20

TCP連接網絡協議

2021-11-09 10:28:12

手機內存技術

2024-07-30 08:22:47

API前端網關

2024-10-10 16:53:53

守護線程編程

2024-04-07 00:00:03

2024-08-20 08:29:55

2024-11-08 09:48:38

異步編程I/O密集

2025-02-18 08:11:17

2022-11-28 00:04:17

2024-01-15 12:16:37

2024-07-26 21:53:59

2023-07-11 00:12:05

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人h视频在线 | 一级一级毛片免费看 | 日韩精品1区2区3区 成人黄页在线观看 | 亚洲国产成人av好男人在线观看 | 日韩电影中文字幕 | 2019精品手机国产品在线 | 美国一级片在线观看 | 91精品国产综合久久精品 | 午夜性视频 | 欧美精品网 | 最新国产精品精品视频 | 久久精品亚洲成在人线av网址 | 久久久久久久久久久高潮一区二区 | 成人国产在线视频 | 亚洲欧美一区二区三区国产精品 | 91精品国产91久久久久久最新 | 国产伦一区二区三区四区 | 久久久久九九九女人毛片 | 欧美精品一区二区三区在线播放 | 日韩超碰| 国产精品美女久久久久久久网站 | 日本aa毛片a级毛片免费观看 | 在线观看黄视频 | 国产美女在线精品免费 | 亚洲精品888 | 色婷婷久久综合 | 黄网站涩免费蜜桃网站 | 国产精品久久久久久久久久久久冷 | 久久男人 | 久久久久一区 | 色婷婷综合久久久中字幕精品久久 | 在线观看www | 国产精品欧美一区二区三区不卡 | 国产精品久久久久久久久久久久久 | 欧美日韩成人在线 | 国产高清视频在线观看播放 | 亚洲风情在线观看 | 香蕉一区二区 | 亚洲在线一区二区 | 一级做a爰片性色毛片 | 秋霞国产|