man poll:

NAME

poll, ppoll - wait for some event on a file descriptor

SYNOPSIS

#include <poll.h>

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

#define _GNU_SOURCE /* See feature_test_macros(7) */

#include <poll.h>

int ppoll(struct pollfd *fds, nfds_t nfds,

const struct timespec *timeout_ts, const sigset_t *sigmask);

DESCRIPTION

poll() performs a similar task to select(2): it waits for one of a set of file descriptors to become ready to per‐

form I/O.

The set of file descriptors to be monitored is specified in the fds argument, which is an array of structures of the

following form:

struct pollfd {

int fd; /* file descriptor */

short events; /* requested events */

short revents; /* returned events */

};

要测试的条件由events指定,函数在相应的revents成员中返回该描述字的状态。(每个描述字都有两个变量,一个为调用值,另一个为返回结果,从而避免使用值结果参数。)

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

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

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

 

  020.#ifndef INFTIM     /*按照书上解释:POSIX规范要求INFTIM在头文件<poll.h>中定义,不过*/

  021.#define INFTIM -1  /*许多系统仍然把它定义在头文件<sys/stropts.h>中,但是经过我的测试*/

  022.#endif             /*即使都包含这两个文件,编译器也找不到,不知何解。索性自己定义了。*/

 



#include"unp.h"
#include<limits.h>//for open_MAX,ubuntuۃбûԐ
#define OPEN_MAX 1024
#define INFTIM -1

int main(int argc,char **argv)
{
int i ,maxi,listenfd,connfd,sockfd;
int nready;
ssize_t n;

socklen_t clilen;
char buf[MAXLINE];

struct pollfd client[OPEN_MAX];
struct sockaddr_in cliaddr,servaddr;
listenfd=Socket(AF_INET,SOCK_STREAM,0);
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family=AF_INET;
servaddr.sin_port=htons(8001);
servaddr.sin_addr.s_addr=htonl(INADDR_ANY);

Bind(listenfd,(SA*)&servaddr,sizeof(servaddr));
Listen(listenfd,LISTENQ);

client[0].fd=listenfd;
client[0].events=POLLRDNORM;
for(i=1;i<OPEN_MAX;i++)
client[i].fd=-1;//
maxi=0;

for(;;)
{
nready=poll(client,maxi+1,INFTIM);
if(client[0].revents & POLLRDNORM )
{ //new client connction
clilen=sizeof(cliaddr);
connfd=Accept(listenfd,(SA*)&cliaddr,&clilen);

for(i=1;i<OPEN_MAX;i++)
{
if(client[i].fd<0)
{
client[i].fd=connfd;//save desc
break;
}
}
if(i==OPEN_MAX)
err_quit("too many client");
client[i].events=POLLRDNORM;
if(i>maxi)
maxi=i;
if(--nready<=0)
continue;
}
for(i=1;i<=maxi;i++)
{
//check all clients for data
if( (sockfd=client[i].fd)<0)
continue;
if(client[i].revents & ( POLLRDNORM | POLLERR))
{
if((n=read(sockfd,buf,MAXLINE))<0)
{
if(errno==ECONNRESET)
{
//conncetion reset by client
Close(sockfd);
client[i].fd=-1;
}
else
err_sys("read error");
}
else if(n==0)
{
//connection close by client
Close(sockfd);
client[i].fd=-1;
}
else Writen(sockfd,buf,n);

if(--nready<=0)
break;
}
}
}
}