【问题标题】:How to get poll()'s POLLHUP equivalent with select()?如何使用 select() 获得 poll() 的 POLLHUP 等效项?
【发布时间】:2014-09-15 15:17:52
【问题描述】:

我目前正在将一些代码从 Linux 移植到 Windows(使用 MinGW)。

根据我understand 的说法,MinGW 不支持 poll(),这是在原版中使用的,所以我正在为select() 重写所有内容。

现在我偶然发现了if (pfd[i].revents & (POLLERR|POLLHUP))...

如何使用select() 获得与此条件相同的条件 - 或者使用 winsock api 或 MinGW 提供的任何内容? POLLERR 部分很简单; if(FD_ISSET (i, &error_fd_set)) 但我对 POLLHUP 部分不知所措。

【问题讨论】:

    标签: c++ c windows mingw


    【解决方案1】:

    你不能。您必须使用“正常”的方式来确定连接是否已关闭,即从中读取。
    就代码而言,它是:

    int rc = select(max_fd + 1, read_set, ..., ..., ...);
    // check rc
    for (int i = 0; i <= max_fd; ++i) {
      if (FD_ISSET(i, &read_set)) { // data incoming on i
         int rc = read(i, ..., ...); // or recv, if you use some flag
         if (rc == 0) {
            // i hung up
        }
      }
    }
    

    否则,您可以使用 WSAPoll,它提供的 API 类似于您在类 UNIX 系统中所期望的 API。

    关于WSAPoll的更多信息。

    【讨论】:

      【解决方案2】:

      根据我的The Linux Programming Interface 副本,内核轮询事件被映射到select() 事件,如下所示:

      // Ready for reading
      #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR)
      // Ready for writing
      #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR)
      // Exceptional condition
      #define POLLEX_SET (POLLPRI)
      

      因此这表明您需要检查“就绪”事件。真正区分 POLLHUP、POLLIN 和 POLLIN | POLLHUP,您可以使用书中的以下图表:

      | ----- Condition or event ---- |
      Data in pipe? | Write end open? | select() | poll()
      no              no                r        | POLLHUP
      yes             yes               r        | POLLIN
      yes             no                r        | POLLIN | POLLHUP
      

      【讨论】:

        猜你喜欢
        • 2015-01-18
        • 2023-02-12
        • 2022-01-01
        • 2016-01-06
        • 2014-10-17
        • 1970-01-01
        • 2010-09-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多