我编写了一个与特定端口上的服务器交互的小程序。该程序工作正常,但是:
一旦程序意外终止,并且此套接字连接一直处于CLOSE_WAIT
状态显示。如果尝试运行程序,它将挂起,并且必须强制将其关闭,这会累积更多的 CLOSE_WAIT
套接字连接。
有没有办法清除这些连接?
我编写了一个与特定端口上的服务器交互的小程序。该程序工作正常,但是:
一旦程序意外终止,并且此套接字连接一直处于CLOSE_WAIT
状态显示。如果尝试运行程序,它将挂起,并且必须强制将其关闭,这会累积更多的 CLOSE_WAIT
套接字连接。
有没有办法清除这些连接?
Answers:
CLOSE_WAIT
表示您的程序仍在运行,并且尚未关闭套接字(内核正在等待它关闭)。添加-p
到netstat
以获取该pid,然后更加有力地将其杀死(SIGKILL
如果需要的话)。那应该摆脱您的CLOSE_WAIT
套接字。您也可以使用ps
来查找pid。
SO_REUSEADDR
用于服务器和TIME_WAIT
套接字,因此不适用于此处。
正如克里斯蒂·克拉克(Crist Clark)所描述的。
CLOSE_WAIT表示连接的本地端已从另一端收到FIN,但是OS正在等待本地端的程序实际关闭其连接。
问题是您在本地计算机上运行的程序没有关闭套接字。这不是TCP调整问题。在程序使连接保持打开状态的同时,连接可以(并且相当正确)永远停留在CLOSE_WAIT中。
本地程序关闭套接字后,操作系统可以将FIN发送到远程端,当您等待FIN的ACK时,该远程端会将您转换为LAST_ACK。收到连接后,连接完成,并从连接表中删除(如果您的终端处于CLOSE_WAIT,则不会以TIME_WAIT状态结束)。
close()
或closesocket()
,取决于使用的平台。
我在最新的Tomcat服务器(7.0.40)上也遇到了同样的问题。连续几天无响应。
要查看打开的连接,可以使用:
sudo netstat -tonp | grep jsvc | grep --regexp="127.0.0.1:443" --regexp="127.0.0.1:80" | grep CLOSE_WAIT
正如提到的这个职位,你可以使用/proc/sys/net/ipv4/tcp_keepalive_time
,以查看值。该值似乎以秒为单位,默认为7200(即2小时)。
要更改它们,您需要进行编辑/etc/sysctl.conf
。
Open/create `/etc/sysctl.conf`
Add `net.ipv4.tcp_keepalive_time = 120` and save the file
Invoke `sysctl -p /etc/sysctl.conf`
Verify using `cat /proc/sys/net/ipv4/tcp_keepalive_time`
即使CLOSE_WAIT连接过多,也意味着您的代码在开始时就出现了问题,这不是很好的做法。
您可能要签出:https : //github.com/rghose/kill-close-wait-connections
该脚本的作用是发出连接正在等待的ACK。
这对我有用。
应该提到的是,Socket
客户端和服务器端的实例都需要显式调用close()
。如果也只有一端调用close()
,则套接字将保持CLOSE_WAIT状态。
您可以使用ss
命令强制关闭套接字;该ss
命令是用于转储套接字统计信息并以类似于netstat的方式(尽管更简单,更快)显示信息的工具。
要杀死处于CLOSE_WAIT状态的任何套接字,请以root用户身份运行此套接字
$ ss --tcp state CLOSE-WAIT --kill