我试图在端口号绑定我的套接字(服务器套接字)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$
Run Code Online (Sandbox Code Playgroud)
icf*_*ntv 59
我也遇到过同样的问题.这是因为您正在关闭与套接字的连接,而不是套接字本身.套接字可以进入TIME_WAIT状态(以确保所有数据都已传输,如果可能,TCP保证传送)并且最多需要4分钟才能发布.
或者,对于真正的详细/技术说明,请查看此链接
确实可能很烦人,但没有真正的方法,它不是一个错误.
Sup*_*mee 21
我知道问题被问到已经有一段时间但是我找到了一个解决方案:
int sockfd;
int option = 1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
Run Code Online (Sandbox Code Playgroud)
这使套接字能够立即重用.
如果这是"错误的",我道歉.我对套接字不太熟悉
如前所述,您的套接字可能进入TIME_WAIT状态.Thomas A. Fine 在这里很好地描述了这个问题.
总结一下,套接字关闭过程如下图所示:
托马斯说:
查看上图,很明显,
TIME_WAIT如果远程端启动闭包,则可以避免.因此,服务器可以通过让客户端先关闭来避免问题.必须设计应用程序协议,以便客户端知道何时关闭.服务器可以安全地关闭以响应来自客户端的EOF,但是如果客户端不正常地离开网络,它还需要在期望EOF时设置超时.在许多情况下,只需在服务器关闭前等待几秒即可.
使用SO_REUSEADDR通常建议在互联网上,但托马斯补充说:
奇怪的是,使用
SO_REUSEADDR实际上可能会导致更难的"已使用的地址"错误.SO_REUSADDR允许您使用卡住的端口TIME_WAIT,但您仍然无法使用该端口建立与其连接的最后一个位置的连接.什么?假设我选择本地端口1010,并连接到foobar.com端口300,然后在本地关闭,留下该端口TIME_WAIT.我可以立即重用本地端口1010连接除foobar.com300端口以外的任何地方.
小智 6
只需输入
unlink [SOCKET NAME]
Run Code Online (Sandbox Code Playgroud)
在终端中,则错误应该不再存在.