通過命令查看所有狀態的個數:
netstat -antlp|awk '/tcp/ {print $6}'|sort|uniq -c
16 CLOSING
130 ESTABLISHED
298 FIN_WAIT1
13 FIN_WAIT2
9 LAST_ACK
7 LISTEN
103 SYN_RECV
5204 TIME_WAIT
各個狀態的含義解釋:
狀態 | 描述 |
---|---|
CLOSED | 無連接是活動的或正在進行 |
LISTEN | 服務器在等待進入呼叫 |
SYN_RECV | 一個連接請求已經到達,等待確認 |
SYN_SENT | 應用已經開始,打開一個連接 |
ESTABLISHED | 正常數據傳輸狀態 |
FIN_WAIT1 | 應用說它已經完成 |
FIN_WAIT2 | 另一邊已同意釋放 |
ITMED_WAIT | 等待所有分組死掉 |
CLOSING | 兩邊同時嘗試關閉 |
TIME_WAIT | 另一邊已初始化一個釋放 |
LAST_ACK | 等待所有分組死掉 |
如發現系統存在大量TIME_WAIT狀態的連接,通過調整內核參數解決,編輯內核文件,加入以下內容:
vim /etc/sysctl.conf
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
然后執行 /sbin/sysctl -p
讓參數生效。
參數含義解釋:
- net.ipv4.tcp_syncookies = 1 表示開啟SYN cookies。當出現SYN等待隊列溢出時,啟用cookies來處理,可防范少量SYN攻擊,默認為0,表示關閉。
- net.ipv4.tcp_tw_reuse = 1 表示開啟重用。允許將TIME-WAIT sockets重新用於新的TCP連接,默認為0,表示關閉。
- net.ipv4.tcp_tw_recycle = 1 表示開啟TCP連接中TIME-WAIT sockets的快速回收,默認為0,表示關閉。
- net.ipv4.tcp_fin_timeout 修改系統默認的 TIMEOUT 時間。
下面附上TIME_WAIT狀態的意義:
客戶端與服務器端建立TCP/IP連接后關閉SOCKET后,服務器端連接的端口狀態為TIME_WAIT,是不是所有執行主動關閉的socket都會進入TIME_WAIT狀態呢?有沒有什么情況使主動關閉的socket直接進入CLOSED狀態呢?主動關閉的一方在發送最后一個 ack 后就會進入 TIME_WAIT 狀態 停留2MSL(max segment lifetime報文最大生存時間)時間這個是TCP/IP必不可少的,也就是"解決"不了的。也就是TCP/IP設計者本來是這么設計的。
主要有兩個原因:
- 1.防止上一次連接中的包,迷路后重新出現,影響新連接(經過2MSL,上一次連接中所有的重復包都會消失)。
- 2.可靠的關閉TCP連接。
在主動關閉方發送的最后一個 ack(fin) ,有可能丟失,這時被動方會重新發fin, 如果這時主動方處於 CLOSED 狀態 ,就會響應 rst 而不是 ack。所以主動方要處於 TIME_WAIT 狀態,而不能是 CLOSED。TIME_WAIT 並不會占用很大資源的,除非受到攻擊。還有,如果一方 send 或 recv 超時,就會直接進入 CLOSED 狀態。
這樣修改完內核參數完,再去netstat查看網絡連接,發現time_wait狀態的連接基本都消失了。
netstat -antlp|awk '/tcp/{print $6}'|sort|uniq -c
8 ESTABLISHED
19 LISTEN
3 SYN_SENT
3 TIME_WAIT