1. 程式人生 > >TIME_WAIT狀態的原因及解決辦法

TIME_WAIT狀態的原因及解決辦法

socket相關索引:https://blog.csdn.net/knowledgebao/article/details/84626184

linux下通過netstat -ano命令,可以檢視到關於socket的狀態:

包括:FIN_WAIT_1、FIN_WAIT_2、CLOSE_WAIT、LAST_ACK、TIME_WAIT、CLOSED、LISTEN、ESTABLISHED等,具體詳見握手和揮手過程。

這裡我們就TIME_WAIT的狀態及原因進行描述:

建立TCP需要3次握手,而終止TCP需要4次互動;具體參考:https://blog.csdn.net/qzcsu/article/details/72861891

三次握手:

四次揮手


1)可以改為長連線,但代價較大,長連線太多會導致伺服器效能問題,而且PHP等指令碼語言,需要通過proxy之類的軟體才能實現長連線;
2)修改ipv4.ip_local_port_range,增大可用埠範圍,但只能緩解問題,不能根本解決問題;
3)客戶端程式中設定socket的SO_LINGER選項;
4)客戶端機器開啟tcp_tw_recycle和tcp_timestamps選項;
5)客戶端機器開啟tcp_tw_reuse和tcp_timestamps選項;
6)客戶端機器設定tcp_max_tw_buckets為一個很小的值;

通過調整核心引數解決,在 /etc/sysctl.conf中加入net.ipv4.tcp_tw_recycle = 1    (表示開啟TCP連線中TIME-WAIT sockets的快速回收,預設為0表示關閉)

 

https://blog.csdn.net/windyf2013/article/details/78756791

  • FIN_WAIT_1: 這個狀態要好好解釋一下,其實FIN_WAIT_1FIN_WAIT_2狀態的真正含義都是表示等待對方的FIN報文。而這兩種狀態的區別是:FIN_WAIT_1狀態實際上是當SOCKET在ESTABLISHED狀態時,它想主動關閉連線,向對方傳送了FIN報文,此時該SOCKET即進入到FIN_WAIT_1狀態。而當對方迴應ACK報文後,則進入到FIN_WAIT_2狀態,當然在實際的正常情況下,無論對方何種情況下,都應該馬上回應ACK報文,所以FIN_WAIT_1
    狀態一般是比較難見到的,而FIN_WAIT_2狀態還有時常常可以用netstat看到。(主動方)
  • FIN_WAIT_2:上面已經詳細解釋了這種狀態,實際上FIN_WAIT_2狀態下的SOCKET,表示半連線,也即有一方要求close連線,但另外還告訴對方,我暫時還有點資料需要傳送給你(ACK資訊),稍後再關閉連線。(主動方)
  • CLOSE_WAIT:這種狀態的含義其實是表示在等待關閉。怎麼理解呢?當對方close一個SOCKET後傳送FIN報文給自己,你係統毫無疑問地會迴應一個ACK報文給對方,此時則進入到CLOSE_WAIT狀態。接下來呢,實際上你真正需要考慮的事情是察看你是否還有資料傳送給對方,如果沒有的話,那麼你也就可以 close這個SOCKET,傳送FIN報文給對方,也即關閉連線。所以你在CLOSE_WAIT狀態下,需要完成的事情是等待你去關閉連線。(被動方)
  • LAST_ACK: 這個狀態還是比較容易好理解的,它是被動關閉一方在傳送FIN報文後,最後等待對方的ACK報文。當收到ACK報文後,也即可以進入到CLOSED可用狀態了。(被動方)
  • TIME_WAIT: 表示收到了對方的FIN報文,併發送出了ACK報文,就等2MSL後即可回到CLOSED可用狀態了。如果FINWAIT1狀態下,收到了對方同時帶FIN標誌和ACK標誌的報文時,可以直接進入到TIME_WAIT狀態,而無須經過FIN_WAIT_2狀態。(主動方)
  • CLOSED: 表示連線中斷。