如何删除CLOSE_WAIT套接字连接

Dil*_*nte 80 sockets linux

我编写了一个与特定端口上的服务器交互的小程序.该程序工作正常,但:

一旦程序意外终止,并且自从该套接字连接显示在CLOSE_WAIT状态之后.如果我尝试运行程序,它会挂起,我必须强行关闭,这会累积更多的 CLOSE_WAIT套接字连接.

有没有办法刷新这些连接?

der*_*ert 68

CLOSE_WAIT表示您的程序仍在运行,并且尚未关闭套接字(内核正在等待它执行此操作).添加-pnetstat获取pid,然后更有力地杀死它(SIGKILL如果需要).那应该摆脱你的CLOSE_WAIT插座.您还可以使用它ps来查找pid.

SO_REUSEADDR用于服务器和TIME_WAIT套接字,因此不适用于此处.

  • 好吧...如果该程序打开了很多连接,那么这个过程可能不是最好的,只有少数那些留在"CLOSE_WAIT"的人:在这种情况下杀死这个过程可能是完全不可能或不合适的(该程序仍然有效,提供服务,与其他连接).只是关闭挂起的连接会更合适.但实际上通常程序本身并没有在本地关闭connectino(CLOSE_WAIT意味着它从另一端接收'FIN'而程序只需要在本地关闭连接).错误报告可能是合适的 (2认同)

小智 35

正如Crist Clark所描述的那样.

CLOSE_WAIT表示连接的本地端已从另一端收到FIN,但操作系统正在等待本端程序实际关闭其连接.

问题是您在本地计算机上运行的程序没有关闭套接字.这不是TCP调优问题.当程序保持连接打开时,连接可以(并且非常正确地)保持在CLOSE_WAIT中.

一旦本地程序关闭套接字,操作系统就可以将FIN发送到远程端,在等待FIN的ACK时将转换为LAST_ACK.收到后,连接完成并从连接表中删除(如果您的结尾处于CLOSE_WAIT状态,则不会以TIME_WAIT状态结束).

  • 如何关闭套接字? (3认同)

Mus*_*did 13

可以通过ss命令强行关闭套接字;该ss命令是一个工具,用于转储套接字统计信息并以与 netstat 类似的方式(虽然更简单和更快)显示信息。

要终止处于 CLOSE_WAIT 状态的任何套接字,请运行它(以 root 身份)

$ ss --tcp state CLOSE-WAIT --kill
Run Code Online (Sandbox Code Playgroud)

您也可以过滤您的操作

$ ss --tcp state CLOSE-WAIT '( dport = 22 or dst 1.1.1.1 )' --kill
Run Code Online (Sandbox Code Playgroud)

  • 这应该是最重要的答案。 (2认同)

mir*_*age 7

尽管过多的CLOSE_WAIT连接意味着您的代码在第一次出现问题,但这被认为是不好的做法.

您可能需要查看:https://github.com/rghose/kill-close-wait-connections

这个脚本的作用是发送连接等待的ACK.

这对我有用.


Ami*_*ara 6

我对最新的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
Run Code Online (Sandbox Code Playgroud)

正如提到的这个职位,你可以使用/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`
Run Code Online (Sandbox Code Playgroud)

  • 答案很混乱.你说非响应状态已经持续了好几天..但是你也试着将保持活动时间设置为仅120秒.即使使用默认值(7200秒),也不应该持续数天,对吗? (3认同)