错误:在将套接字与地址绑定时地址已在使用中,但端口号由“netstat”免费显示

Posted

技术标签:

【中文标题】错误:在将套接字与地址绑定时地址已在使用中,但端口号由“netstat”免费显示【英文标题】:Error: Address already in use while binding socket with address but the port number is shown free by `netstat` 【发布时间】:2011-07-03 15:54:05 【问题描述】:

我尝试将我的套接字(服务器套接字)绑定到端口号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$ 

【问题讨论】:

您是否还仔细关闭了在服务器运行时与服务器建立的所有连接? 【参考方案1】:

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

或者,对于真正详细/技术性的解释,check this link

这当然很烦人,但这不是错误。关于SO_REUSEADDR的使用,请参阅@Vereb 对此答案的评论。

【讨论】:

在您链接的页面上有一个可能的解决方案。您可以对套接字使用 SO_REUSEADDR 选项。在此处查看 setsockopt:linux.die.net/man/3/setsockopt【参考方案2】:

试试这样的 netstat:netstat -ntp,没有-l。它将显示 tcp 连接 TIME_WAIT 状态。

【讨论】:

【参考方案3】:

只需输入

unlink [SOCKET NAME]

在终端中,那么错误应该不再存在。

【讨论】:

那是 Unix 域套接字。问题是关于 TCP 套接字的。【参考方案4】:

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

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

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

【讨论】:

【参考方案5】:

我知道这个问题已经有一段时间了,但我找到了解决方案:

int sockfd;
int option = 1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));

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

如果这是“错误的”,我深表歉意。我对套接字不是很有经验

【讨论】:

我喜欢你将wrong 放在引号中的方式,暗示任何不同意你的人都是错误的。 引号更像是“如果它有效,那就没有错”之类的东西。我意识到这可能不是首选方式,如果有人知道“正确”的方式,我会很感兴趣。 1 是什么意思? 这是不久前的事情,所以如果我错了请纠正我,但我相信这是因为当你希望套接字不逗留时,它必须是“非零”。我找不到任何具体的内容,但您可以在以下位置阅读更多信息:ibm.com/support/knowledgecenter/en/SSB23S_1.1.0.15/gtpc2/…【参考方案6】:

我收到的错误是:

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

我发现的解决方法是:

    我不得不禁用 selinux

    在 /usr/lib/systemd/system/cockpit 服务中,我更改了 行:

    #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 
    

所以你可以看到我拿出了关于 selinux 的论点 然后我跑了:

systemctl daemon-reload
systemctl start cockpit.service

然后我浏览到:

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

这一切都在 Fedora25 机器上。 9090 端口已经 使用firewall-cmd添加

【讨论】:

【参考方案7】:

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

总结一下,socket关闭流程如下图:

托马斯 说:

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

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

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

【讨论】:

【参考方案8】:

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

【讨论】:

以上是关于错误:在将套接字与地址绑定时地址已在使用中,但端口号由“netstat”免费显示的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails - 地址已在使用中 - 为“0.0.0.0”端口 3000 (Errno::EADDRINUSE) 绑定 (2)

地址已在使用中... C 中的套接字

PHP:TCP 套接字,“无法绑定地址”

Python:绑定套接字:“地址已在使用中”

Errno 98(地址已在使用中)Python Opencv

由于套接字绑定错误,Apache不会在启动时启动,而是手动启动