MENU

「Linux Socket」使用POLL机制处理多连接

• 2017 年 06 月 07 日 • Linux开发

使用select函数可以处理socket多连接的问题,使用POLL也可以实现同样的功能,且调用方式更加简单。

1. 原型

#include <poll.h>  
int poll(struct pollfd fds[], nfds_t nfds, int timeout);  

pollfd结构如下,也在poll.h源文件中:

struct pollfd {  
    int fd;            //文件描述符  
    short events;      //要求查询的事件掩码  
    short revents;     //返回的事件掩码
};

poll函数使用pollfd类型的结构来监控一组文件句柄

2. 参数

  • fds:存放需要被检测状态的Socket描述符;与select不同(select函数在调用之后,会清空检测socket描述符的数组),每当调用这个函数之后,系统不会清空这个数组,而是将有状态变化的描述符结构的revents变量状态变化,操作起来比较方便;
  • nfds:用于标记数组fds中的struct pollfd结构元素的总数量;
  • timeout:poll函数调用阻塞的时间,单位是MS(毫秒)

3. 返回值

  • 0表示socket描述符没有状态变化,并且调用超时
  • -1表示失败
  • 成功则返回结构体中revents不为0的文件描述符个数

4. pollfd结构监控的事件类型

注:events域中请求的任何事件都可能在revents域中返回:

POLLIN        // 有数据可读
POLLRDNORM       // 有普通数据可读
POLLRDBAND      // 有优先数据可读
POLLPRI       // 有紧迫数据可读
POLLOUT         // 写数据不会导致阻塞
POLLWRNORM     // 写普通数据不会导致阻塞
POLLWRBAND      // 写优先数据不会导致阻塞
POLLMSGSIGPOLL   // 消息可用

除此,revents还能返回:

POLLER     指定的文件描述符发生错误
POLLHUP   指定的文件描述符挂起事件
POLLNVAL  指定的文件描述符非法

如上是events事件掩码的值域,POLLIN|POLLPRI类似于select的读事件,POLLOUT|POLLWRBAND类似于select的写事件。
当events属性为POLLIN|POLLOUT,表示监控是否可读或可写。
在poll返回时,即可通过检查revents变量对应的标志位与events是否相同,比如revents中POLLIN事件标志位被设置,则表示文件描述符可以被读取。

5. 代码示例

int sockfd;             //套接字句柄  
struct pollfd pollfds;  
int timeout;  
  
timeout = 5000;  
pollfds.fd = sockfd;                //设置监控sockfd  
pollfds.events = POLLIN|POLLPRI;            //设置监控的事件  
  
for(;;){  
    switch(poll(&pollfds,1,timeout)){       //开始监控  
    case -1:                    //函数调用出错  
        printf("poll error \r\n");  
    break;  
    case 0:  
        printf("time out \r\n");  
    break;  
    default:                    //得到数据返回  
        printf("sockfd have some event \r\n");  
        printf("event value is 0x%x",pollfds.revents);  
    break;  
    }  
}   
标签: Linux, socket
返回文章列表 文章二维码
本页链接的二维码
打赏二维码