客户端调用 close() 后,TCP 套接字发送缓冲区中的数据会发生什么变化?



如果客户端调用write()函数将大量数据写入socketfd的缓冲区,然后调用close(socketfd),客户端还会将缓冲区中剩余的数据发送给服务器吗?

客户端还会将缓冲区中剩余的数据发送到服务器吗?

这取决于情况

默认情况下,是。但是,您可以使用SO_LINGER套接字选项禁用该行为:

https://man7.org/linux/man-pages/man7/socket.7.html

SO_LINGER
设置或获取SO_LINGER选项。自变量是linger结构。

struct linger {
int l_onoff;    /* linger active */
int l_linger;   /* how many seconds to linger for */
};

启用后,close(2)shutdown(2)将不会返回,直到套接字的所有排队消息都已成功发送或达到延迟超时。否则,调用将立即返回,并在后台完成关闭。当套接字作为exit(2)的一部分关闭时,它总是在后台徘徊。

这将在MSDN for Windows上进行更详细的讨论(closesocket()相当于Windows的套接字close(),但Posix系统的行为类似(:

优雅关机、林格选项和插座关闭

在Windows套接字中,shutdown函数和WSASendDisconnect函数都可以用于启动关闭序列,而closesocket函数用于解除分配套接字句柄并释放任何相关资源。然而,由于closesocket函数隐式地导致关闭序列发生(如果尚未发生(,因此会产生一定程度的混乱。事实上,依赖这个特性并使用closesocket来启动关闭序列和释放套接字句柄已经成为一种相当常见的编程实践。

为了便于使用,sockets接口通过socket选项机制提供了控制,该机制允许程序员指示隐式关机序列是正常的还是中止的,以及closesocket函数是否应该延迟(不是立即完成(,以便有时间完成正常的关机序列。这些重要的区别以及以这种方式使用closesocket的后果仍然没有被广泛理解。

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

  • 中止关闭序列,立即从closesocket返回
  • 优雅关闭,延迟返回,直到关闭序列完成或经过指定的时间间隔。如果在正常关机序列完成之前时间间隔过期,则会出现中止关机序列,并且closesocket返回
  • 优雅的关闭,立即返回--允许在后台完成关闭序列。尽管这是默认行为,但应用程序无法知道优雅的关闭序列何时(或是否(真正完成

最新更新