错误:在绑定具有地址的套接字时,地址已经在使用,但端口号通过`netstat`显示

我试图绑定我的套接字(服务器套接字)端口号8000 。 它为我工作和做了这项工作。 在代码结束时,我也closures了套接字。 我再次运行我的代码的瞬间,它告诉我,该地址已被使用。 我打印了错误值strerror(errno);的含义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$ 

我也遇到了同样的问题。 这是因为你closures了与套接字的连接,而不是套接字本身。 套接字可以进入TIME_WAIT状态(为了确保所有的数据已经传输,如果可能,TCP保证传输) 并且最多需要4分钟才能释放 。

或者,对于一个真正的详细/技术解释, 检查这个链接

可以肯定的是,这可能很麻烦,但是没有真正的方法,这不是一个错误。

试试像这样的netstat -ntpnetstat -ntp ,不带-l 。 它将以TIME_WAIT状态显示tcp连接。

我知道这个问题已经有一段时间了,但我能find一个解决scheme:

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

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

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

只要input

 unlink [SOCKET NAME] 

在terminal,那么错误应该不存在了。

如前所述,您的套接字可能会以TIME_WAIT状态进入。 Thomas A. Fine 在这里详细描述了这个问题。

综上所述,套接字closures过程如下图所示:

套接字关闭过程

托马斯说:

看上面的图表,很明显,如果远程端启动closures,则可以避免TIME_WAIT 。 所以服务器可以通过让客户先closures来避免问题。 应用程序协议的devise必须使客户端知道何时closures。 服务器可以安全地closures来响应来自客户端的EOF,但是当客户端不正常地离开networking时,它也将需要设置超时以预期EOF。 在许多情况下,在服务器closures之前等待几秒钟就足够了。

通常在互联网上使用SO_REUSEADDR ,但托马斯补充说:

奇怪的是,使用SO_REUSEADDR实际上会导致更多的“地址已经被使用”的错误。 SO_REUSADDR允许您使用TIME_WAIT卡住的端口,但仍不能使用该端口build立到最后连接的地方的连接。 什么? 假设我select本地端口1010,并连接到foobar.com端口300,然后closures本地,在TIME_WAIT留下该端口。 我可以立即重用本地端口1010连接到foobar.com端口300以外的任何地方。

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

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

我认为这是由TCP / IPdevise原理造成的。 当服务器将数据发送回客户端时,必须保证数据发送成功,为此,即使服务器应用程序closures了此套接字,OS(Linux)也需要监视连接。 但我仍然相信内核套接字devise师可以改善这个问题。

我收到的错误是:

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

我发现的修复是:

  1. 我必须禁用selinux
  2. 在/ 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 

然后我浏览到:

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

这是所有在fedora25机器上。 已经使用firewall-cmd添加了9090端口