ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

如何停止CLOSE_WAIT端口:How do I remove a CLOSE_WAIT socket connection

2022-07-04 20:01:04  阅读:141  来源: 互联网

标签:do socket connection program close CLOSE WAIT


104

I have written a small program that interacts with a server on a specific port. The program works fine, but:

Once the program terminated unexpectedly, and ever since that socket connection is shown in CLOSE_WAIT state. If I try to run a program it hangs and I have to force it close, which accumulates even more CLOSE_WAIT socket connections.

Is there a way to flush these connections?

Share Improve this question   edited Apr 6, 2016 at 6:53 user avatar Chris Martin 29.5k88 gold badges7373 silver badges131131 bronze badges asked Apr 9, 2013 at 13:31 user avatar Dilletante 1,73144 gold badges1818 silver badges1818 bronze badges
  • 5 You can't (and shouldn't). CLOSE_WAIT is a state defined by TCP for connections being closed waiting for the counterpart to acknowledge this.  – vonbrand  Apr 9, 2013 at 14:54
  • 1 See also unix.stackexchange.com/questions/10106/… ... which I won't vote as a duplicate, because it'd wind up closing the question as off-topic.  – derobert  Apr 9, 2013 at 17:32
  • 5 @vonbrand No it isn't, it is exactly the opposite. It is the state for a connection which has already been closed by the peer and is waiting for the local application to close its end.  – user207421  Apr 9, 2013 at 22:01 
  •   If you are using Commons HttpClient then nuxeo.com/blog/… has a lot of relevant information. From RFC 2616, Section 14: HTTP/1.1 applications that do not support persistent connections MUST include the "close" connection option in every message.  – Mayank Ahuja  Jun 23, 2015 at 0:53 
Add a comment

7 Answers

91  

CLOSE_WAIT means your program is still running, and hasn't closed the socket (and the kernel is waiting for it to do so). Add -p to netstat to get the pid, and then kill it more forcefully (with SIGKILL if needed). That should get rid of your CLOSE_WAIT sockets. You can also use ps to find the pid.

SO_REUSEADDR is for servers and TIME_WAIT sockets, so doesn't apply here.

Share Improve this answer   answered Apr 9, 2013 at 17:30 user avatar derobert 48k1212 gold badges9191 silver badges122122 bronze badges
  • 7 well... kiling the process may not be the best if that program open a lot of connection, only a few of those staying in "CLOSE_WAIT" : in that case killing the process may be completely impossible or unappropriate (the program still works and provides services, with those other connections). Just closing the pending connection would be much more appropriate. but indeed it is usually the program itself which is not closing locally the connectino (CLOSE_WAIT means it received 'FIN' from the other end and the program just have to close the connection locally). A bug report may be appropriate  – Olivier Dulac  Jul 5, 2017 at 14:09 
Add a comment   43

As described by Crist Clark.

CLOSE_WAIT means that the local end of the connection has received a FIN from the other end, but the OS is waiting for the program at the local end to actually close its connection.

The problem is your program running on the local machine is not closing the socket. It is not a TCP tuning issue. A connection can (and quite correctly) stay in CLOSE_WAIT forever while the program holds the connection open.

Once the local program closes the socket, the OS can send the FIN to the remote end which transitions you to LAST_ACK while you wait for the ACK of the FIN. Once that is received, the connection is finished and drops from the connection table (if your end is in CLOSE_WAIT you do not end up in the TIME_WAIT state).

Share Improve this answer   edited Jun 26, 2017 at 15:11 user avatar Bhargav Rao 46.2k2727 gold badges120120 silver badges136136 bronze badges answered Jul 25, 2013 at 11:11 user avatar user2618402 44744 silver badges22 bronze badges
  • 6 how to close the socket??  – Divyang Shah  May 1, 2015 at 10:51
  • 1 You close the handle you have to the socket you opened. Use close() or closesocket(), depending on which platform you are using.  – Remy Lebeau  Aug 22, 2015 at 23:21
  •   @RemyLebeau I suppose the real question is how to wire-it-up in situations where it doesn't automatically happen. Why would a socket not be closed? It couldn't be waiting for incoming data (because of the FIN it would be canceled). Is it a failure to respond to the error condition of such a read operation?  – sehe  Jan 23, 2021 at 16:37
Add a comment 25

You can forcibly close sockets with ss command; the ss command is a tool used to dump socket statistics and displays information in similar fashion (although simpler and faster) to netstat.

To kill any socket in CLOSE_WAIT state, run this (as root)

$ ss --tcp state CLOSE-WAIT --kill

You may also filter your action

$ ss --tcp state CLOSE-WAIT '( dport = 22 or dst 1.1.1.1 )' --kill
Share Improve this answer   edited Mar 28, 2021 at 9:00     answered Apr 10, 2020 at 11:22 user avatar Mustapha Hadid 1,1741414 silver badges2626 bronze badges
  • 5 That should be the top answer.  – Tom  Jan 3, 2021 at 9:26
  •   can we apply a filter to kill only a specific port?  – Mohammad Faisal  Feb 24, 2021 at 11:15
  •   @MohammadFaisal Yeah, of course; you may kill (or list if you want) all sockets by their source or destination port like this: sudo ss --tcp --kill sport = 54576 or dport = :ssh  – Mustapha Hadid  Feb 24, 2021 at 15:12
  •   @MustaphaHadid: Thanks. This is a helpful answer but in my case the result of ss is tcp 0 0 1.1.16.1:57212 1.1.16.28:8081 CLOSE_WAIT - with no process id and therefore the --kill was unsuccessful. And therefore I am unable to free up this port 57212.  – Mohammad Faisal  Feb 25, 2021 at 7:19
Add a comment   9

Even though too much of CLOSE_WAIT connections means there is something wrong with your code in the first and this is accepted not good practice.

You might want to check out: https://github.com/rghose/kill-close-wait-connections

What this script does is send out the ACK which the connection was waiting for.

This is what worked for me.

Share Improve this answer   answered Nov 14, 2014 at 10:58 user avatar mirage 57199 silver badges1919 bronze badges
  •   you send act to close-wait socket. with not works .. if works ,why ?  – Chinaxing  Dec 18, 2015 at 6:07
  •   I am guessing, the OS has already sent the FIN to the remote host. The remote host probably cannot reply with the ACK that the socket is expecting.  – mirage  Dec 18, 2015 at 10:06 
  •   yes, that's right ( from kernel code). but I also doubt about the SEQ of the packet you send, which is "10", does kernel not check it ?  – Chinaxing  Dec 21, 2015 at 8:45
  •   Probably not. I think I tried with many random numbers, and they seemed to work.  – mirage  Dec 24, 2015 at 7:41
Add a comment 8

I'm also having the same issue with a very latest Tomcat server (7.0.40). It goes non-responsive once for a couple of days.

To see open connections, you may use:

sudo netstat -tonp | grep jsvc | grep --regexp="127.0.0.1:443" --regexp="127.0.0.1:80" | grep CLOSE_WAIT

As mentioned in this post, you may use /proc/sys/net/ipv4/tcp_keepalive_time to view the values. The value seems to be in seconds and defaults to 7200 (i.e. 2 hours).

To change them, you need to edit /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`
Share Improve this answer   edited Apr 13, 2017 at 12:36 user avatar CommunityBot 111 silver badge answered Jul 17, 2013 at 10:46 user avatar Amil Waduwawara 1,61211 gold badge1616 silver badges1414 bronze badges
  • 6 the answer is confusing. you said the non-responsive states has gone for several days.. but then you also try to set the keep alive time to only 120 seconds. even with the default value (7200 sec), it shouldn't last for several days, right?  – fanchyna  Sep 11, 2015 at 16:52
Add a comment 3

It should be mentioned that the Socket instance in both client and the server end needs to explicitly invoke close(). If only one of the ends invokes close() then too, the socket will remain in CLOSE_WAIT state.

Share Improve this answer   answered Feb 16, 2019 at 9:04 user avatar Binita Bharati 4,16511 gold badge3535 silver badges2222 bronze badges Add a comment 1

It is also worth noting that if your program spawns a new process, that process may inherit all your opened handles. Even after your own program closs, those inherited handles can still be alive via the orphaned child process. And they don't necessarily show up quite the same in netstat. But all the same, the socket will hang around in CLOSE_WAIT while this child process is alive.

I had a case where I was running ADB. ADB itself spawns a server process if its not already running. This inherited all my handles initially, but did not show up as owning any of them when I was investigating (the same was true for both macOS and Windows - not sure about Linux).

标签:do,socket,connection,program,close,CLOSE,WAIT
来源: https://www.cnblogs.com/felixzh/p/16444247.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有