CloseWait

TCP连接过程中的状态图如下:

上图中给出的是客户端主动关闭连接,当然服务端也可以主动关闭连接。主动关闭连接的那一端会出现TIME_WAIT状态,被动关闭连接的那一端会出现CLOSE_WAIT状态。

如果服务端出现了大量的CLOSE_WAIT状态,一般来说是服务程序出现了问题。比如说,客户端发起的请求,可能设置了5秒的超时,如果服务端处理这个请求的时间超过5秒(比如长时间的查数据库)或者没有主动关闭连接,那么这个连接在服务端就会是CLOSE_WAIT的状态。

接下来,我们来模拟服务端出现CLOSE_WAIT的情况:

客户端发起连接,5秒后主动关闭连接,服务端在连接建立的10分钟后关闭连接,那么在客户端关闭连接后服务端关闭连接前,服务端就会进入CLOSE_WAIT的状态

服务端与客户端代码

  • server.py

import socket
import time

if __name__=="__main__":
    print "Server is starting"
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.bind(('10.142.232.162', 8001))
    sock.listen(5)
    print "Server is listenting port 8001, with max connection 5"
    while True:
        connection,address = sock.accept()
        time.sleep(600)   
        connection.close()
  • client.py

import sys
import socket
import time

if __name__=="__main__":    
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(('10.142.232.162', 8001))   
    time.sleep(5)
    print 'client closed connection'
    sock.close()

启动server与client

把server.py放在10.142.232.162上,把client.py放在10.142.232.163上,先启动server,再启动client

查看状态

等10秒钟client主动关闭连接后,查看server与client的状态

client端的 FIN_WAIT_2 状态只会维持60秒,这是由系统的 tcp_fin_timeout 定义的,而server端的 CLOSE_WAIT 状态却会长时间存在,直到600秒后server也关闭连接,或者server进程挂掉

  • client端

$ netstat -apn | grep 8001
(No info could be read for "-p": geteuid()=580 but you should be root.)
tcp        0      0 10.142.232.163:58768    10.142.232.162:8001     FIN_WAIT2   -
  • server端

$ netstat -apn | grep 8001
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
tcp        0      0 10.142.232.162:8001     0.0.0.0:*               LISTEN      130228/python       
tcp        1      0 10.142.232.162:8001     10.142.232.163:58768    CLOSE_WAIT  130228/python

Last updated

Was this helpful?