正常关闭、挥之不去选项和套接字关闭

以下材料作为关闭套接字连接关闭套接字连接的主题进行了说明。 必须区分关闭套接字连接和关闭套接字之间的差异。

关闭套接字连接涉及两个终结点之间的协议消息交换,后称为关闭序列。 定义了两个常规的关闭序列类:正常和中止(也称为硬)。 在正常关闭序列中,任何已排队但尚未传输的数据都可以在连接关闭之前发送。 在中止关闭中,任何未发送的数据都将丢失。 关闭序列(正常或中止)也可用于向关联的应用程序提供FD_CLOSE指示,表示正在关闭。

另一方面,关闭套接字会导致套接字句柄解除分配,以便应用程序不能以任何方式引用或使用套接字。

在 Windows 套接字中,关闭 函数和 WSASendDisconnect 函数都可用于启动关闭序列,而 closesocket 函数用于解除分配套接字句柄并释放任何关联的资源。 然而,由于 closesocket 函数隐式导致关闭序列(如果尚未发生),则会出现一些混淆。 事实上,它已成为一种相当常见的编程做法,它依赖于此功能,并使用 closesocket 来启动关闭序列并解除分配套接字句柄。

为了便于使用此用法,套接字接口通过套接字选项机制提供控件,使程序员能够指示隐式关闭序列是否应正常或中止,以及 closesocket 函数是否应挥之不去(未立即完成),以允许正常关闭序列完成的时间。 这种重要的区别和使用 封闭 的影响仍然不广为人知。

通过为套接字选项SO_LINGER和SO_DONTLINGER建立适当的值,可以使用 closesocket 函数获取以下类型的行为:

  • 中止关闭序列,立即从 closesocket返回。
  • 正常关闭,延迟返回,直到关闭序列完成或指定的时间间隔过。 如果时间间隔在正常关闭序列完成之前过期,将发生中止关闭序列,关闭集 返回。
  • 正常关闭,立即返回 - 允许关闭序列在后台完成。 尽管这是默认行为,但应用程序无法知道何时(或是否)正常关闭序列实际上完成。

有关 SOL_SOCKET 套接字选项徘徊 结构的参考部分,更详细地讨论了使用SO_LINGER和SO_DONTLINGER套接字选项以及关联的 挥发 结构。

一种可用于最大程度地减少连接拆解期间发生问题的可能性的一种方法是避免依赖 closesocket启动的隐式关闭。 请改用两个显式关闭函数之一,关闭WSASendDisconnect。 这反过来会导致对等应用程序接收FD_CLOSE指示,指示已收到所有挂起的数据。 为了说明这一点,下表显示了应用程序客户端和服务器组件将调用的函数,其中客户端负责启动正常关闭。

客户端 服务器端
(1) 调用 关闭(s,SD_SEND),以发出会话结束信号,并且客户端没有更多要发送的数据。
(2) 接收FD_CLOSE,指示正在进行的正常关闭,并且已收到所有数据。
(3) 发送任何剩余的响应数据。
(仅限本地计时意义)获取FD_READ和调用 recv 以获取服务器发送的任何响应数据。 (4) 调用 关闭(s,SD_SEND),以指示服务器没有要发送的数据。
(5) 接收FD_CLOSE指示。 (仅限本地计时意义)调用 closesocket
(6) 调用 关闭