我正在阅读有关使用 SO_LINGER 套接字选项通过将逗留时间设置为零来有意“暗杀”时间等待状态的内容。该书的作者接着说我们永远不应该这样做,并且一般来说我们永远不应该干扰时间等待状态。然后他立即建议使用 SO_REUSEADDR 选项来绕过时间等待状态。

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

有帮助吗?

解决方案 2

我做了更多阅读,这是我对发生的事情的理解(希望是正确的):

当您在设置了 SO_REUSEADDR 的套接字上调用 close 时(或者您的应用程序崩溃),会发生以下序列:

  1. TCP 发送发送缓冲区中的所有剩余数据和 FIN
  2. 如果调用 close ,它会立即返回,而不指示任何剩余数据是否已成功传递。
  3. 如果数据已发送,则对等方会发送数据 ACK
  4. 对等方发送 FIN 的 ACK 并发送自己的 FIN 数据包
  5. 对等方的 FIN 被确认,套接字资源被释放。
  6. 套接字不进入TIME-WAIT。

当您关闭 SO_LINGER 时间设置为零的套接字时:

  1. TCP 丢弃发送缓冲区中的所有数据
  2. TCP 向对端发送 RST 数据包
  3. 套接字资源被释放。
  4. 套接字不进入TIME-WAIT

因此,除了将 linger 设置为零是一种黑客行为和糟糕的风格之外,它也是一种不礼貌的行为,因为它不会彻底关闭连接。

其他提示

TIME_WAIT是完全正常。它在本地端后跟一个TCP FIN ACK从远程位置的TCP FIN之后发生。在TIME_WAIT你只是等待任何杂散数据包在本地地址到达。然而,如果存在丢失的或杂散分组然后TIME_WAIT确保TTL或“生存时间”再次使用地址之前到期。

如果您使用SO_REUSEADDR那么你基本上是说,我会假设有没有遗漏的数据包。这是越来越有可能与现代的,可靠的,TCP网络。虽然它仍然是可能的话,是不可能的。

设置SO_LINGER零使你启动一个异常接近,也被称为“地一声关上的连接。”在这里,你不尊重TIME_WAIT和忽略杂散分组的方法可行。

如果你看到FIN_WAIT_1那么这可能会导致问题,因为响应您的FIN远程位置尚未发送TCP FIN ACK。因此该进程不是被杀或TCP FIN ACK丢失由于网络分区或坏的路线。

当你看到CLOSE_WAIT你有问题,在这里,你正在泄漏的连接为给定TCP FIN当不发送TCP FIN ACK。

我使用SO_REUSEADDR到配绑定()中,某些其它程序已经有一个连接打开一个本地端口。事实证明,这个特殊的使用会不会导致一个问题,只要没有两个插座尽量听()在同一时间同一地址/端口组合。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top