三次握手,四次揮手。javascript
意思是tcp創建鏈接時須要三次交互來完成,A發起鏈接java
A --- SYN --> B A <-- SYN + ACK --- B (1) A --- ACK --> B
而關閉tcp鏈接須要四次交互,A發起關閉bash
A --- FIN --> B A <-- ACK --- B (1) A <-- FIN --- B A --- ACK --> B (2)
這裏在(1)時B開始處於CLOSE_WAIT狀態,一直到收到ACK後B才轉爲CLOSED ,而A就處於TIME_WAIT狀態,一直到2MSL(Max Segament Lifetime)才轉爲CLOSED服務器
爲何須要2MSL才真正轉爲CLOSED?是由於須要緩衝時間萬一B丟失ACK重發FIN的話還能夠回覆ACK,還有就是2MSL後「迷失」在網絡上的包所有失效網絡
大量的 TIME_WAIT 和 CLOSE_WAIT 會形成服務器的鏈接資源被浪費甚至佔滿後致使服務器服務拒絕,怎麼解決?tcp
net.ipv4.tcp_tw_recycle = 1 #開啓快速回收,默認0 net.ipv4.tcp_tw_reuse = 1 #開啓重用,默認0 net.ipv4.tcp_fin_timeout = 30 # 減少fin_timeout,默認60,單位s
系統參數的配置能夠解決time_wait,可是close_wait就沒那麼簡單了spa
通常都是服務端的代碼問題。code
絕大多數都是客戶端發起關閉,這樣可知HTTP服務器應該會有不少TIME_WAIT,不過當http使用keep-alive後服務端會主動斷連。ip