在进程退出时释放绑定端口
Posted
技术标签:
【中文标题】在进程退出时释放绑定端口【英文标题】:Releasing bound ports on process exit 【发布时间】:2010-10-07 15:01:31 【问题描述】:如何确保绑定到端口的套接字在进程退出时被正确释放,以便可以重用该端口,而bind()
不会因 EADDRINUSE 而失败?我编写了一个小程序,它只创建一个套接字,将其绑定到一个固定端口,等待连接,然后立即终止。当我重新运行程序时,bind()
调用失败并显示 EADDRINUSE,但如果我等待几分钟,它就会成功。
有没有办法可以显式地“解除绑定”套接字,从而释放端口号?
【问题讨论】:
【参考方案1】:使用 SO_REUSEADDR 套接字选项将允许您立即重新启动程序。
int iSetOption = 1;
...
sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
setsockopt(_sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&iSetOption,
sizeof(iSetOption))
...
【讨论】:
但请注意,从技术上讲,使用 SO_REUSEADDR 违反了 TCP/IP 协议,这使得绑定该端口的下一个程序可以(尽管不太可能)拾取用于原始程序的数据包。 非常好,正是我想要的。【参考方案2】:即使在close()
之后,TCP/IP 堆栈也会保持端口忙碌一段时间 - 套接字将保持在 TIME_WAIT
和 TIME_WAIT2
状态。
如果我没记错的话,通常需要 2 分钟,所以如果您需要使用相同的端口,请在绑定之前立即在您的套接字上设置 SO_REUSEADDR
选项,就像 Ivo Bosticky 建议的那样。
【讨论】:
【参考方案3】:不完全是您问题的答案,但为了完整性:
在 Windows 上,您可以设置 TcpTimedWaitDelay 注册表值将释放关闭的 TCP 连接的超时设置为低至 30 秒。
【讨论】:
以上是关于在进程退出时释放绑定端口的主要内容,如果未能解决你的问题,请参考以下文章