在进程退出时释放绑定端口

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_WAITTIME_WAIT2 状态。

如果我没记错的话,通常需要 2 分钟,所以如果您需要使用相同的端口,请在绑定之前立即在您的套接字上设置 SO_REUSEADDR 选项,就像 Ivo Bosticky 建议的那样。

【讨论】:

【参考方案3】:

不完全是您问题的答案,但为了完整性:

在 Windows 上,您可以设置 TcpTimedWaitDelay 注册表值将释放关闭的 TCP 连接的超时设置为低至 30 秒。

【讨论】:

以上是关于在进程退出时释放绑定端口的主要内容,如果未能解决你的问题,请参考以下文章

如何验证两个检查点之间是否已释放所有内存分配?

程序中止或退出时是不是释放 pthread_mutex_t*?

释放 TCP/IP 端口?

是否可以防止zend引擎释放资源?

C# kill线程正常释放资源?

释放 TCP/IP 端口?