1.poll 函数:
int poll(struct pollfd *fds,nfds_t nfds,int timeout);
其中第一个参数表示struct pollfd 结构体的数组,struct pollfd 的结构体如下:
struct pollfd{
int fd;
short events;
short revents;
}
第二个参数表示最大描述符的个数加一。第三个参数表示超时限制规定的时间。
代码:
#include "unp.h"
#define FD_MAXSIZE 1024
#include<poll.h>
int main(void){
int listenfd,connfd,nready;
if((listenfd = socket(AF_INET,SOCK_STREAM,0))<0)
ERR_EXIT("socket");
struct sockaddr_in cliaddr,servaddr;
memset(&servaddr,0,sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(45678);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
ERR_EXIT("bind");
listen(listenfd,SOMAXCONN);
int on = 1;
if(setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on))<0)
ERR_EXIT("setsockopt");
struct pollfd client[FD_MAXSIZE];
int i =0;
for(i = 0;i<FD_MAXSIZE;i++){
client[i].fd = -1;
}
int maxi = 0;
int maxfd = listenfd;
char recvbuf[1024];
client[0].fd = listenfd; //我们把0号位用来监听是否有客户端过来。
client[0].events = POLLIN; //我们关心的是写入操作。因此我们需要把events位置设置成POLLIN。
int num = 0;
while(1){
memset(recvbuf,0,sizeof(recvbuf));
nready = poll(client,maxfd+1,-1); //将第三个参数设置成-1 , 也就是一直阻塞下去,直到poll函数有可读事件发生。
if(client[0].revents & POLLIN){ //如果监听套接字的描述符有可读事件。
socklen_t len = sizeof(cliaddr);
connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&len); //accept
struct sockaddr_in peeraddr;
socklen_t lens = sizeof(struct sockaddr_in);
getpeername(connfd,(struct sockaddr*)&peeraddr,&lens);
printf("ip = %s , port = %d \n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port)); //打印对方的地址和端口。
for(i = 0;i<FD_MAXSIZE;i++){
if(client[i].fd == -1){
client[i].fd = connfd;
client[i].events = POLLIN; //遍历一遍pollfd数组(不需要遍历完),找到第一个,并设置成POLLIN
printf("%d \n",++num);
if(i > maxi)
maxi = i;
break;
}
}
if(i == FD_MAXSIZE){
printf("too many clients\n");
}
}
for(i = 1;i<= maxi;i++){ //遍历一遍pollfd 数组(到maxi),看看哪个数组成员发生了可读事件。
if(client[i].fd == -1)
continue;
int con = client[i].fd;
if(client[i].revents & POLLIN){ //发生了可读事件。
int ret = readline(con,recvbuf,sizeof(recvbuf));
if(ret < 0)
ERR_EXIT("readn");
else if(ret == 0){
client[i].fd =-1;
close(con);
continue;
}
printf(recvbuf,stdout);
writen(con,recvbuf,ret);
}
}
}
return 0;
}