以前一直在windows上开发网络,很少用到poll这个函数,前几日看到zmq中,有提供zmq_poll函数接口,忽想起linux下的poll函数,找出学习之。
函数原型:int poll(struct pollfd fds[], nfds_t nfds,int timeout);
函数是某些Unix系统提供的用于执行与select()函数同等功能的函数。
类型:
typedef unsigned long nfds_t;
结构体:
struct pollfd{
int fd; //需要被检测或者选择文件描述符
short events; //监视文件描述符的事件掩码,由用户来设置这个域,即对文件描述符fd上感兴趣的事件,
short revents; //revents域是文件描述符的操作结果事件掩码,内核在调用返回时设置这个域,即文件描述符fd上当前实际发生的事件。
};
events域中请求的任何事件都可能在revents域中返回
参数:
fds是一个struct pollfd结构类型的数组,用于存放需要检测其状态的socket描述符
nfds是nfds_t类型的参数,用于标记fds数组中的结构体元素的总数量
timeout是poll函数调用阻塞的时间,但与毫秒
函数返回值
//>0:数组fds中准备好读、写、或出错状态的那些socket描述符的总数量。
//=0:数组fds中没有任何socket准备好读、写、或出错;此时poll超时,超时时间是timeout毫秒
//-1:调用失败,同时会自动设置全局变量errno
经常检测的事件标识
POLLIN //有数据可读 常用
POLLRDNORM //有普通数据可读 常用
POLLRDBAND //有优先数据可读
POLLPRI //有紧迫数据可读
POLLOUT //写数据不会导致阻塞 常用
POLLWRNORM //写普通数据不会导致阻塞 常用
POLLWRBAND //写优先数据不会导致阻塞
POLLMSG //SIGPOLL消息可用
POLLERR //指定的文件描述符发生错误 常用
POLLHUP //指定的文件描述符挂起事件
POLLNVAL //制定的文件描述符非法
需要关注多个事件的话,对这些常量标记之间按位或运算即可。
如:fds[nIndex].events = POLLIN | POLLOUT | POLLERR
对socket描述符fd的读写、写、异常事件感兴趣,操作如下:
fds[nindex].events = POLLIN | POLLOUT | POLLERR
当poll函数返回时,需要检测socket描述符上发生的事件
if(fds[index].revents & POLLOUT) == POLLOUT)
{
//发送数据
}
/检测可写