Unix网络编程-poll函数

poll函数起源于SVR3,最初局限于流设备。SVR4取消了这种限制,允许poll工作在任何描述符上。poll提供的功能于select类似,不过在处理流设备时,它能够提供额外的信息。

函数原型:

#include

int  poll( struct  pollfd*  fdarray,  unsigned  long  nfds, int  timeout);

            返回:若有就绪描述符则为其数目,若超时则为0,若出错则为-1

用于指定测试某个给定描述符fd的条件。

struct  pollfd {

        int    fd;        /* descriptor  to  check */

        short  events;    /* event of  interest  on  fd*/

        short  revent;    /* event  that occurred  on  fd */

};

要测试的条件由events成员指定,函数在相应的revents成员中返回该描述符的状态。(每个描述符都有两个变量,一个为调用值,另一个为返回结果,从而避免使用值-结果参数。回想select函数中间三个参数值都是值-结果参数。)这两个成员中的每一个都由指定某个特定条件的一位或多位构成。下图列车了用于指定events标志以及测试revents标志的一些常值。

我们将该图分为三个部分:第一部分处理输入的四个常值,第二部分处理输出的三个常值,第三部分处理错误的三个常值。其中第三部分的三个常值不能在events中设置,但是当相应条件存在时就在revents中返回。

poll识别三类数据:普通(normal)、优先级带(priority band)和高优先级(high  priority)。这些术语均出自基于流的实现。

就TCP和UDP套接字而言,以下条件引起poll返回特定的revent。不幸的是,POSIX在其poll的定义中留了许多空洞(也就是说有许多方法可返回相同的条件)。

1) 所有正规tcp数据和所有udp数据都被认为是普通数据。

2) tcp的带外数据被认为优先级带数据。

3) 当tcp连接的读半部关闭时(譬如收到了一个来自对端的FIN),也被认为是普通数据,随后的读操作将返回0。

4) tcp连接存在错误即可认为是普通数据,也可以认为是错误(POLLERR)。无论哪种情况,随后的读操作将返回-1,并把errno设置成合适的值。这可用于处理诸如接收到RST和发生超时等条件。

5) 在监听套接字上有新的连接可用既可认为是普通数据,也可以认为是优先级数据。大多数实现视之为普通数据。

6) 非阻塞式connect的完成被认为是使相应套接字可写。

结构数组中元素的个数是由nfds参数指定。

timeout参数指定poll函数返回前等待多长时间。他是一个指定应等待毫秒数的正值。下图给出了他的可能取值。

INFTIM常值被定义为一个负值。如果系统不能提供毫秒级精度的定时器,该值就向上舍入到最接近的支持的值。

当发生错误时,poll函数的返回值为-1,若定时器到时之前没有任何描述符就绪,则返回0,否则返回就绪描述符的个数,即revents成员值非0的描述符个数。

如果我们不再关心某个特定描述符,那么可以把他对应的pollfd结构的fd成员设置成一个负值。poll函数将忽略这样的pollfd结构的events成员,返回时将他的revents成员的值置为0。

你可能感兴趣的:(Unix网络编程-poll函数)