1.1、函数定义
int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout);
作用: 等待监听的所有fd相应事件的产生。
1.2、参数详解:
1) int epfd: epoll_create()函数返回的epoll实例的句柄。
2) struct epoll_event * events: 接口的返回参数,epoll把发生的事件的集合从内核复制到 events数组中。events数组是一个用户分配好大小的数组,数组长度大于等于maxevents。(events不可以是空指针,内核只负责把数据复制到这个 events数组中,不会去帮助我们在用户态中分配内存)
3) int maxevents: 表示本次可以返回的最大事件数目,通常maxevents参数与预分配的events数组的大小是相等的。
4) int timeout: 表示在没有检测到事件发生时最多等待的时间,超时时间(>=0),单位是毫秒ms,-1表示阻塞,0表示不阻塞。
1.3、返回值:
成功返回需要处理的事件数目。失败返回0,表示等待超时。
#include<stdio.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/epoll.h>
#include<string.h>
#include<unistd.h>
#define SERV_PORT 8000
#define EPOLL_SIZE 500
#define BUF_SIZE 65535
int read_msg(int fd){
char buf[BUF_SIZE];
bzero(buf, BUF_SIZE);
int len = read(fd, buf, BUF_SIZE);
printf(buf);
return 0;
}
int main(){
int listen_fd, ep_fd;
struct sockaddr_in servaddr;
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(SERV_PORT);
bind(listen_fd, (struct sockaddr*)&servaddr, sizeof(servaddr));
listen(listen_fd, 100);
ep_fd = epoll_create(EPOLL_SIZE);
static struct epoll_event events[EPOLL_SIZE];
struct epoll_event ev;
memset(&ev, 0, sizeof(struct epoll_event));
ev.data.fd = listen_fd;
ev.events = EPOLLIN;
epoll_ctl(ep_fd, EPOLL_CTL_ADD, listen_fd, &ev);
while(1){
int ep_cnt = epoll_wait(ep_fd, events, EPOLL_SIZE, -1);
printf("%d\n", ep_cnt);
if (ep_cnt < 0 ){
break;
}
for(int i =0; i < ep_cnt; i++){
int sockfd = events[i].data.fd;
if (sockfd == listen_fd){
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
int client_fd = accept(listen_fd, (struct sockaddr*)&client_addr, &client_len);
printf("client connect.\n");
struct epoll_event client_ev;
client_ev.data.fd = client_fd;
client_ev.events = EPOLLIN;
epoll_ctl(ep_fd, EPOLL_CTL_ADD, client_fd, &client_ev);
}
else
{
read_msg(sockfd);
}
}
}
close(listen_fd);
close(ep_fd);
return 0;
}
运行验证