TCP漫談之為啥需要timewait狀態

2021-10-04 13:27:48 字數 1240 閱讀 6931

tcp的狀態狀態轉化圖如下所示,其中time_awit狀態是closed之前的乙個狀態,等待2個msl時間。

為啥需要time_awit狀態呢?為啥不直接進入closed狀態呢?這樣不就能更快的釋放資源給新的連線使用了嗎?而是還需要等待2msl(linux預設)時間。

有兩個原因,第乙個原因是為了防止「迷路的資料報」,如下圖所示,如果在第乙個連線裡面第三個資料報由於底層網路故障延遲送達。等待新的連線建立後,這個遲到的資料報才到達,那麼將會導致接收資料紊亂。

第二個原因則更加簡單,如果因為最後乙個ack丟失,那麼對方將一直處於last ack狀態,如果此時重新發起新的連線,對方將返回rst包拒絕請求,將會導致無法建立新連線。

為此,設計了time_awit狀態。如果在高併發情況下,如果能將time_awit的tcp復用

那麼便可以極大的提高併發效率,time_awit的tcp復用是指可以將處於time_awit狀態的連線重複利用起來,從time_awit轉化為established,繼續使用。linux核心通過net.ipv4.tcp_tw_reuse引數控制是否開啟time_awit狀態復用。那麼讀者可能很好奇,之前不是說time_awit設計之初是為了解決上面兩個問題的嗎?如果直接復用不是會導致上面兩個問題嗎?這裡先介紹linux預設開啟的乙個tcp時間戳策略net.ipv4.tcp_timestamps = 1.

時間戳開啟後,針對第乙個迷路資料報的問題,由於晚到資料報的時間戳過早會被直接丟棄,不會導致新連線資料報紊亂。針對第二個問題,當開啟reuse後,當對方處於last-ack狀態時,傳送syn包會返回fin,ack包,然後客戶端傳送rst讓服務端關閉請求,從而客戶端便可以再次傳送syn建立新的連線了。

最後還需要提醒讀者的是,linux 4.1核心版本之前除了tcp_tw_reuse以外,還有乙個引數tcp_tw_recycle,這個引數就是強制**time_wait狀態的連線,它會導致nat環境丟包,所以不建議開啟,這個在之前的blog已經分享過了。

TCP連線的過程,也稱之為三次握手

tcp建立連線,也稱之為三次握手。那麼我現在來簡述一下這個tcp連線的過程 第一次握手,客戶端傳送syn給伺服器,客戶端的狀態為syn send,伺服器接收到請求後,狀態從listen變成syn rcvd。第二次握手,伺服器傳送syn ack給客戶端,客戶端接收到資料報。第三次握手,客戶端傳送ack...

python輪胎 Python之為世界貢獻你的輪子

第一步,註冊賬號 第二步,設定你的輪子資訊 就是你的包的結構 wheelname wheelname init py wheelname.py setup.py 複製 from setuptools import setup,find packages setup name wheelname ve...

Django學習筆記之為Model新增Action

在使用django自帶的admin後台的時候,他提供了一些預設的指令可以對資料進行操作,比如批量刪除,修改等 同樣的我們也可以新增自己的指令。django版本 1.8 python版本 3.4 models.py class story models.model 編輯story狀態 status c...