我正在阅读有关使用SO_LINGER套接字选项通过将延迟时间设置为零来故意“暗杀”时间等待状态的问题。然后,本书的作者继续说我们永远不应该这样做,一般来说我们永远不应该干涉时间等待状态。然后,他立即建议使用SO_REUSEADDR选项来绕过时间等待状态。
我的问题是,有什么区别?在这两种情况下,您都会过早地终止时间等待状态,并承担接收重复段的风险。为什么一个好,另一个坏?
答案 0 :(得分:2)
TIME_WAIT绝对正常。它发生在本地端的TCP FIN之后,然后是来自远程位置的TCP FIN ACK。在TIME_WAIT中,您只是在等待任何杂散数据包到达本地地址。但是,如果丢失或丢失数据包,则TIME_WAIT确保在再次使用该地址之前TTL或“生存时间”到期。
如果您使用SO_REUSEADDR,那么您基本上是在说,我会假设没有杂散数据包。现在,可靠的TCP网络越来越有可能。尽管仍有可能,但不大可能。
将SO_LINGER设置为零会导致您启动异常关闭,也称为“关闭连接”。这里你不尊重TIME_WAIT并忽略了迷路数据包的可能性。
如果您看到FIN_WAIT_1,那么这可能会导致问题,因为远程位置尚未发送TCP FIN ACK以响应您的FIN。因此,由于网络分区或路由不良,进程被杀死或TCP FIN ACK丢失。
当您看到CLOSE_WAIT时遇到问题,此处您正在泄漏连接,因为在给定TCP FIN时您没有发送TCP FIN ACK。
答案 1 :(得分:1)
我做了一些阅读,这是我对发生的事情的理解(希望是正确的):
当你在设置了SO_REUSEADDR(或你的应用程序崩溃)的套接字上调用close时,会发生以下序列:
当SO_LINGER时间设置为零时关闭套接字:
除了设置为零并且设置为零的事实之外,它也是一种糟糕的举止,因为它不会通过干净的关闭连接。
答案 2 :(得分:0)
我已将SO_REUSEADDR用于通配符bind()到本地端口,其他一些程序已经打开了一个连接。事实证明,只要没有两个套接字同时尝试在同一个addr / port组合上侦听(),这种特殊用途就不会出现问题。