套接字关闭后仍处于LISTEN状态

Socket remaining in LISTEN state after closing

本文关键字:LISTEN 状态 套接字      更新时间:2023-10-16

所以,我打开一个端口上的套接字,关闭它,并试图打开另一个。在应用程序半重启后(它卸载了大多数库并重新加载它们,等等,所以我没有不必要地打开/关闭)。

我发现在我调用套接字上的close()之后,它确实从/proc/pid/fd中删除了套接字,但是套接字仍然在netstat -nlp中侦听:

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -               

(以root身份运行,所以你可以看到它没有绑定到我的进程)

SO_REUSEADDR插座,TCP_NODELAY设置

所以我遇到了一个类似的问题,即使在关闭服务器套接字后,应用程序的套接字仍然处于LISTEN状态:

// Before shutdown
#27 72.23 tcp        0      0 0.0.0.0:6001            0.0.0.0:*               LISTEN      333/RunTests
#27 72.23 tcp        0      0 127.0.0.1:57412         127.0.0.1:6001          ESTABLISHED 333/RunTests
#27 72.23 tcp        0      0 127.0.0.1:6001          127.0.0.1:57412         ESTABLISHED 333/RunTests
// Call shutdown(srv_socket, SHUT_RDWR)
#27 72.23 tcp        0      0 0.0.0.0:6001            0.0.0.0:*               LISTEN      333/RunTests        
#27 72.23 tcp        0      0 127.0.0.1:57412         127.0.0.1:6001          CLOSE_WAIT  333/RunTests
#27 72.23 tcp        0      1 127.0.0.1:6001          127.0.0.1:57412         FIN_WAIT1   333/RunTests
// Call close(srv_socket)
#27 72.24 tcp        0      0 0.0.0.0:6001            0.0.0.0:*               LISTEN      333/RunTests
#27 72.24 tcp        0      0 127.0.0.1:57412         127.0.0.1:6001          CLOSE_WAIT  333/RunTests
#27 72.24 tcp        0      1 127.0.0.1:6001          127.0.0.1:57412         FIN_WAIT1   -
// A few ms later
#27 75.03 tcp        0      0 0.0.0.0:6001            0.0.0.0:*               LISTEN      333/RunTests

证明@user207421在我们的情况下是正确的:我们认为我们正在关闭服务器套接字,但实际上关闭的是在服务器端代表与客户端连接的套接字(由accept()返回的那个),而不是实际侦听连接的服务器套接字(由socket()返回的那个)。

使用shutdown(clt_socket, SHUT_RDWR)(在客户端连接套接字上),然后使用close(srv_socket)(在实际的服务器套接字上),效果非常好。