TIME-WAIT暗杀和SO_REUSEADDR之间有什么区别

时间:2009-02-25 21:31:07

标签: sockets time-wait

我正在阅读有关使用SO_LINGER套接字选项通过将延迟时间设置为零来故意“暗杀”时间等待状态的问题。然后,本书的作者继续说我们永远不应该这样做,一般来说我们永远不应该干涉时间等待状态。然后,他立即建议使用SO_REUSEADDR选项来绕过时间等待状态。

我的问题是,有什么区别?在这两种情况下,您都会过早地终止时间等待状态,并承担接收重复段的风险。为什么一个好,另一个坏?

3 个答案:

答案 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时,会发生以下序列:

  1. TCP发送发送缓冲区中的所有剩余数据和FIN
  2. 如果关闭被调用,则会立即返回,而不会指示是否已成功传送任何剩余数据。
  3. 如果发送了数据,则对等体发送数据ACK
  4. 对等体发送FIN的ACK并发送它自己的FIN数据包
  5. 对等的FIN被激活并且套接字资源被释放。
  6. 套接字不会进入TIME-WAIT。
  7. 当SO_LINGER时间设置为零时关闭套接字:

    1. TCP丢弃发送缓冲区中的所有数据
    2. TCP向对等方发送RST数据包
    3. 取消分配套接字资源。
    4. 套接字未进入TIME-WAIT
    5. 除了设置为零并且设置为零的事实之外,它也是一种糟糕的举止,因为它不会通过干净的关闭连接。

答案 2 :(得分:0)

我已将SO_REUSEADDR用于通配符bind()到本地端口,其他一些程序已经打开了一个连接。事实证明,只要没有两个套接字同时尝试在同一个addr / port组合上侦听(),这种特殊用途就不会出现问题。