关闭崩溃程序打开的套接字

关闭崩溃程序打开的套接字

我打开了数千个套接字,有时程序崩溃,导致可用的套接字少了很多。有没有办法清理这些挂起的套接字?

答案1

套接字最终由 Unix 内核关闭;崩溃的程序与正常的没有 oaclose()/shutdown()调用的程序退出没有什么不同。

您的问题可能与 TCP/IP 状态机的 TIME_WAIT 状态有关,应使用 SO_REUSEADDR 选项解决。确认这一点的一种方法是等待大约 5 分钟,然后再在崩溃后重新启动。如果您发现现在有足够的套接字可用,您应该研究 TIME_WAIT 逻辑并解决它。如果等待技巧不能解决您的问题,则您的程序中可能存在其他问题,需要识别。

这是关于这个主题的一篇好文章,
TIME_WAIT 及其对协议和可扩展客户端服务器系统的设计影响

摘录两段供参考,

TIME_WAIT 通常也称为 2MSL 等待状态。这是因为转换到 TIME_WAIT 的套接字将停留在该状态一段时间,持续时间为 2 x 最大段生命周期。MSL 是任何段(在所有意图和目的上,构成 TCP 协议一部分的数据报)在被丢弃之前可以在网络上保持有效的最长时间。此时间限制最终受用于传输 TCP 段的 IP 数据报中的 TTL 字段的限制。不同的实现为 MSL 选择不同的值,常见值为 30 秒、1 分钟或 2 分钟。RFC 793 指定 MSL 为 2 分钟,Windows 系统默认使用此值,但可以使用 TcpTimedWaitDelay 注册表设置进行调整。

(PS:因此4+1请等待我上面建议的测试)

更改 2MSL 延迟通常是机器范围的配置更改。您可以尝试使用 SO_REUSEADDR 套接字选项在套接字级别解决 TIME_WAIT 问题。这允许在已存在具有相同地址和端口的现有套接字时创建套接字。新套接字本质上劫持了旧套接字。您可以使用 SO_REUSEADDR 允许在具有相同端口的套​​接字已处于 TIME_WAIT 状态时创建套接字,但这也可能导致拒绝服务攻击或数据窃取等问题。

本文介绍了另一种方法。但这种方法也存在其他注意事项。

还有另一种终止 TCP 连接的方法,即中止连接并发送 RST 而不是 FIN。这通常是通过将 SO_LINGER 套接字选项设置为 0 来实现的。这会导致待处理数据被丢弃,连接以 RST 中止,而不是传输待处理数据并以 FIN 彻底关闭连接。重要的是要意识到,当连接被中止时,对等端之间可能正在流动的任何数据都将被丢弃,并且会立即发送 RST;通常作为错误,表示“对等端已重置连接”。远程对等端知道连接已中止,并且两个对等端都不会进入 TIME_WAIT。

在使用这些方案之前,最好先了解 TCP 机器的行为,这样你就不会无意中引入其他需要稍后调试的情况。所以至少要完整地阅读那篇文章:-)

相关内容