在epoll边缘触发模式下,哪些常见的编程错误会导致CLOSE_WAIT卡住?

What common programming mistakes can cause stuck CLOSE_WAIT in epoll edge triggered mode?

本文关键字:误会 错误 编程 CLOSE 卡住 WAIT 常见 边缘 epoll 模式      更新时间:2023-10-16

我想知道什么常见的编程情况/错误可能导致服务器进程,我已经进入CLOSE_WAIT,但实际上没有关闭套接字。

我想做的是触发这种情况,这样我就可以解决它。在正常的开发环境中,我无法触发它,但是在实时服务器上使用的相同代码偶尔会触发它们,因此在许多天之后,我们有数百个。

搜索close_wait,它实际上似乎是一个非常普遍的问题,甚至在成熟的和应该编写良好的服务,如nginx。

CLOSE_WAIT基本上是指远端关闭套接字,但本地应用程序尚未在其上调用close()。这通常发生在而不是期望从套接字读取数据,因此不关注其可读性的情况下。

为了方便起见,许多应用程序总是监视套接字的可读性,以检测关闭。

一个可以尝试的场景是:

  1. 对端发送2k的数据并立即关闭数据
  2. 你的套接字然后注册epoll并获得可读性通知
  3. 你的应用程序只读取1k的数据
  4. 停止监控套接字的可读性
  5. (我不确定边缘触发epoll是否最终会将关机事件作为单独的事件交付)。

参见:

(from man epoll_ctl)

EPOLLRDHUP(自Linux 2.6.17起)流套接字对端关闭连接,或关闭正在写的一半连接。(这个标志对书写特别有用简单的代码使用边缘触发监控时检测对等端关闭)