int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);
返回值:若有就绪描述符则为其数目,若超时则为0,若出错则为-1.
第一个参数是指向一个结构数组第一个元素的指针。
struct pollfd {
int fd; /*待测试的描述符fd*/
short events; /*fd上感兴趣的事件*/
short revents; /*fd上发生的事件*/
};
测试条件由event指定,函数在相应的revents成员中返回该描述符的状态。
(每个描述符都有两个变量,从而避免了select的值--结果参数).
数组fdarray中元素的个数是由nfds参数指定,历史上这个参数定义为unsigned long,似乎过分大了。定义为无符号整数就够了。UNIX 98为该参数定义了名为nfds_t的新的数据类型。
int poll(struct pollfd *fdarray, nfds_t nfds, int timeout);
timeout参数指定poll函数返回前等待多长时间。它是一个指定应等待毫秒数的正值。
1)INFTIM 永远等待
2)0 立即返回,不阻塞进程
3)>0 等待指定数目的毫秒数。
poll函数的事件标志符值
常量
|
说明
|
POLLIN
|
普通或优先级带数据可读
|
POLLRDNORM
|
普通数据可读
|
POLLRDBAND
|
优先级带数据可读
|
POLLPRI
|
高优先级数据可读
|
POLLOUT
|
普通数据可写
|
POLLWRNORM
|
普通数据可写
|
POLLWRBAND
|
优先级带数据可写
|
POLLERR
|
发生错误
|
POLLHUP
|
发生挂起
|
POLLNVAL
|
描述字不是一个打开的文件
|
-
#include <unistd.h>
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <signal.h>
-
#include <sys/socket.h>
-
#include <sys/types.h>
-
#include <sys/wait.h>
-
#include <errno.h>
-
#include <netinet/in.h>
-
#include <arpa/inet.h>
-
#include <sys/wait.h>
-
#include <strings.h>
-
#include "readn.h"
-
#include <poll.h>
-
#define INFTIM -1
-
#define OPEN_MAX 1024
-
int main(int argc,char *argv[])
-
{
-
int ret = 0;
-
int listen_fd;
-
int conn_fd;
-
struct sockaddr_in server_addr;
-
struct sockaddr_in client_addr;
-
socklen_t len;
-
struct pollfd fdarray[OPEN_MAX];
-
nfds_t nfds;
-
int i;
-
char recvline[MAXLINE];
-
int n;
-
int fd;
-
-
listen_fd = socket(AF_INET,SOCK_STREAM,0);
-
-
if(listen_fd < 0) {
-
printf("socket error\n");
-
return -1;
-
}
-
-
bzero(&server_addr,sizeof(struct sockaddr_in));
-
-
server_addr.sin_family = AF_INET;
-
server_addr.sin_port = htons(10000);
-
//server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
-
ret = inet_pton(AF_INET,"127.0.0.1",&server_addr.sin_addr.s_addr);
-
if(ret < 0) {
-
printf("inet_pton error\n");
-
close(listen_fd);
-
return ret;
-
}else if(ret == 0) {
-
printf("the second parameter of inet_addr is null\n");
-
}
-
-
if(bind(listen_fd,(struct sockaddr*)&server_addr,sizeof(struct sockaddr)) == -1) {
-
printf("bind error\n");
-
close(listen_fd);
-
return -1;
-
}
-
-
-
if(listen(listen_fd,1024) == -1) {
-
printf("listen error\n");
-
close(listen_fd);
-
return -1;
-
}
-
fdarray[0].fd = listen_fd;
-
fdarray[0].events = POLLRDNORM;
-
nfds = 1;
-
for(i = 1;i < OPEN_MAX;i++)
-
fdarray[i].fd = -1;
-
-
for(;;) {
-
ret = poll(fdarray,nfds,INFTIM);
-
if(ret < 0) {
-
printf("poll error, errno=%d\n",errno);
-
}else if (ret == 0) {
-
printf("poll timeout\n");
-
}
-
if(fdarray[0].revents == POLLRDNORM) {
-
len = sizeof(client_addr);
-
conn_fd = accept(listen_fd,(struct sockaddr*)&client_addr,&len);
-
if(conn_fd < 0) {
-
printf("accept error,errno=%d\n",errno);
-
if(errno == EINTR)
-
continue;
-
return -1;
-
}
-
-
for(i = 1;i < OPEN_MAX;i++) {
-
if(fdarray[i].fd == -1) {
-
break;
-
}
-
}
-
if(i == OPEN_MAX) {
-
printf("error too many fds,exceeds OPEN_MAX\n");
-
return -1;
-
}
-
-
fdarray[i].fd = conn_fd;
-
fdarray[i].events = POLLRDNORM;
-
nfds++;
-
-
if(--ret <= 0)
-
continue;
-
}
-
for(i = 1; i <= nfds;i++)
-
{
-
if((fd = fdarray[i].fd) < 0)
-
continue;
-
-
if(fdarray[i].revents == POLLRDNORM) {
-
/*TODO::handle on conn_fd*/
-
if((n=read(fd,recvline,MAXLINE)) == 0) {
-
close(fd);
-
fd = -1;
-
}else {
-
writen(fd,recvline,n);
-
}
-
if(--ret <= 0)
-
break;
-
}
-
}
-
}
-
return 0;
-
}
阅读(825) | 评论(0) | 转发(0) |