gpt4 book ai didi

sockets - FIN_WAIT2 状态是否曾经由于关闭连接发起者而出现?

转载 作者:行者123 更新时间:2023-12-03 11:59:15 25 4
gpt4 key购买 nike

我正在做一些 POSIX 套接字编程,但遇到了问题。我编写了一个使用非阻塞套接字的应用程序。因为我目前正在针对正在开发的服务器开发客户端,所以偶尔会发送错误的应用程序级消息。发生这种情况时,我唯一的恢复方法是完全重新建立连接以强制通信进入已知状态。

我通过在非阻塞套接字上发出 POSIX“close()”来重置连接。然后我请求一个新的套接字并重新建立连接。

但是,我发现的一件事是所有重置都会导致旧连接出现“FIN_WAIT2”。运行 netstat 命令时,有大量没有关联 PID 的 FIN_WAIT2(我猜这些被认为是孤立的,可以尝试内核连接超时?)。

无论如何,我很好奇为什么所有这些旧连接都堆积在 netstat 中。我已经阅读了一些关于 TCP 状态的资料,我看到的 FIN_WAIT2 似乎是由于服务器(即在我的情况下不是关闭发起者)没有响应它成功关闭的消息。这是为什么?

FIN_WAIT2 通常与非关闭启动器端的错误相关联吗?还是我在我的应用程序中做了一些阻止接收 FIN 消息的事情?我使用非阻塞套接字的事实与它有什么关系吗?

最佳答案

总之,是的,您可能在非关闭启动器端存在错误。它与非阻塞套接字无关。非阻塞套接字只会影响应用程序与其操作系统之间的交互。

重要的是要了解双方 双方都必须终止套接字连接以便正确清理状态。听起来您的服务器没有关闭套接字的末端。一种可能的情况:

  • 服务器创建监听套接字,绑定(bind)它等。
  • 服务器调用接受
  • 客户端调用 connect 创建连接(双方的 TCP 状态移动到 ESTABLISHED
  • send/recv/send/recv/etc(状态仍然是ESTABLISHED)
  • 客户端调用关闭;客户端操作系统向服务器发送FIN数据包(客户端操作系统将套接字状态移动到FIN_WAIT1)
  • 服务器操作系统发送ACK以确认客户端机器的FIN(服务器操作系统将套接字状态移动到CLOSE_WAIT;客户端操作系统将套接字状态移动到FIN_WAIT2)
  • 服务器(程序)永远不会关闭它的套接字,因此服务器操作系统永远不会发送FIN,因此客户端操作系统会将套接字保持在FIN_WAIT2 状态。 (服务器套接字状态在 CLOSE_WAIT 中表示)

客户端套接字状态可以在FIN_WAIT2 状态停留很长时间,甚至永远,这取决于操作系统的实现。例如,Linux 有一个可调变量 tcp_fin_timeout,它指定空闲连接将在 FIN_WAIT2 中保留多长时间;但是 TCP 标准没有为 FIN_WAIT2 指定超时。 (请注意,客户端程序并不知道这一切。它已经关闭了套接字,套接字文件描述符已被销毁,套接字不再可供它访问;这一切都由操作系统。)

如果发生这种情况,您可以尝试重新启动服务器程序(因为当您终止服务器进程时,服务器的操作系统将自动关闭其所有打开的文件,这将导致 FIN在任何仍然打开的套接字上发送)。我想您会看到重新启动服务器会导致所有这些客户端套接字进入 TIME_WAIT 状态,它们会在该状态停留一小段时间,然后自行消失。 (TIME_WAIT 指定的超时机制。)

另见 TCP 状态图:

TCP State Diagram

关于sockets - FIN_WAIT2 状态是否曾经由于关闭连接发起者而出现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50352505/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com