我尝试在端口号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$
答案 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很好地描述了这个问题。
总结一下,套接字关闭过程如下图所示:
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
我发现的修复是:
在/ 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
所以你可以看到我拿出了关于selinux的论点 然后我跑了:
systemctl daemon-reload
systemctl start cockpit.service
然后我浏览了:
我接受了自签名证书 能够成功登录驾驶舱并正常使用。
这一切都在fedora25机器上。 9090港口已经有了
已使用firewall-cmd
答案 7 :(得分:0)
对于AF_UNIX,您可以使用call unlink(path);在“服务器”应用程序中的close()套接字后