错误:使用地址绑定套接字时已经使用的地址但是`netstat`显示了端口号

时间:2011-02-24 15:25:04

标签: c linux sockets

我尝试在端口号8000绑定我的套接字(服务器套接字)。它起作用并为我做了工作。在代码的最后我也关闭了套接字。在下一个瞬间,我再次运行我的代码,它向我显示该地址已被使用。我打印了错误值strerror(errno);的含义,以查看我的代码是否在每个点都正常工作。要检查端口是否空闲,我使用netstat进行了检查,但它显示端口号8000是免费的。它发生在我身上很多次。每次我等待几秒钟然后它再次开始工作。我正在使用c语言。那么他的操作系统对于这种行为的原因是什么呢?

再过几秒钟后,我运行代码,然后就可以了。

anirudh@anirudh-Aspire-5920:~/Desktop/testing$ sudo ./a.out 
Socket Creation: Success
File open: Success
Socket Bind: Address already in use
Socket Listen: Address already in use
^C
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ sudo netstat -lntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      1348/lighttpd   
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      984/sshd        
tcp        0      0 127.0.0.1:631           0.0.0.0:*               LISTEN      1131/cupsd      
tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      1211/mysqld     
tcp6       0      0 :::22                   :::*                    LISTEN      984/sshd        
tcp6       0      0 ::1:631                 :::*                    LISTEN      1131/cupsd      
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ sudo ./a.out 
Socket Creation: Success
File open: Success
Socket Bind: Address already in use
Socket Listen: Address already in use
^C
anirudh@anirudh-Aspire-5920:~/Desktop/testing$ 

8 个答案:

答案 0 :(得分:51)

我也遇到过同样的问题。这是因为您正在关闭与套接字的连接,而不是套接字本身。套接字可以进入TIME_WAIT状态(以确保所有数据都已传输,如果可能,TCP保证传送)and take up to 4 minutes to release

或者,对于真正的详细/技术说明,check this link

确定可能很烦人,但是没有真正的解决方法,这不是一个错误。

答案 1 :(得分:21)

我知道问题被问到已经有一段时间但是我能够找到解决方案:

npm link

这使套接字能够立即重用。

如果这是“错误的”,我道歉。我对套接字不太熟悉

答案 2 :(得分:19)

尝试使用这样的netstat:netstat -ntp,不使用-l。它将显示tcp连接 TIME_WAIT州。

答案 3 :(得分:6)

输入

unlink [SOCKET NAME]
终端中的

,则错误应该不再存在。

答案 4 :(得分:6)

如前所述,您的套接字可能进入TIME_WAIT状态。 Thomas A. Fine here很好地描述了这个问题。

总结一下,套接字关闭过程如下图所示:

Socket closing process

Thomas 说:

  

查看上图,很明显TIME_WAIT可以   如果远程端启动关闭,则避免。所以服务器可以   通过让客户先关闭来避免问题。应用程序   必须设计协议,以便客户端知道何时关闭。该   但是,服务器可以安全地关闭以响应来自客户端的EOF   它还需要在预期EOF时设置超时   客户端不合理地离开了网络。在许多情况下简单   在服务器关闭前等待几秒就足够了。

通常在互联网上建议使用SO_REUSEADDR,但 Thomas 添加:

  

奇怪的是,使用SO_REUSEADDR实际上会导致更难的地址   已经在使用"错误。 SO_REUSADDR允许您使用的端口   卡在TIME_WAIT,但您仍然无法使用该端口建立   连接到它连接的最后一个地方。什么?假设我选择   本地端口1010,并连接到foobar.com端口300,然后关闭   在本地,将该端口留在TIME_WAIT。我可以重用本地端口1010   马上连接到foobar.com端口300以外的任何地方。

答案 5 :(得分:1)

即使icfantv对这个问题的回答已经很完美,我的测试中仍有更多的发现。

作为处于侦听状态的服务器套接字,如果它只处于侦听状态,甚至它接受请求并从客户端获取数据,但没有任何数据发送动作。我们仍然可以在它停止后立即重启服务器。但是,如果在服务器端向客户端发生任何数据发送操作,则相同的服务(相同端口)重启将出现此错误:(地址已在使用中)。

我认为这是由TCP / IP设计原则引起的。当服务器将数据发送回客户端时,必须确保数据发送成功,为此,OS(Linux)需要监视连接,即使服务器应用程序关闭了此套接字。 但我仍然相信内核插槽设计师可以改善这个问题。

答案 6 :(得分:0)

我收到的错误是:

cockpit.socket: Failed to listen on sockets: Address already in use

我发现的修复是:

  1. 我不得不禁用selinux
  2. 在/ usr / lib / systemd / system / cockpit服务中我改变了 line:

    #ExecStartPre=/usr/sbin/remotectl certificate --ensure --user=root --group=cockpit-ws --selinux-type=etc_t
    

    为:

    #ExecStartPre=/usr/sbin/remotectl certificate --ensure --user=root --group=cockpit-ws 
    
  3. 所以你可以看到我拿出了关于selinux的论点 然后我跑了:

    systemctl daemon-reload
    systemctl start cockpit.service
    
    然后我浏览了:

    我接受了自签名证书 能够成功登录驾驶舱并正常使用。

    这一切都在fedora25机器上。 9090港口已经有了 已使用firewall-cmd

    添加

答案 7 :(得分:0)

对于AF_UNIX,您可以使用call unlink(path);在“服务器”应用程序中的close()套接字后