epoll处理多客户端连接
1、关键词:epoll_event、epoll_create、epoll_ctl、epoll_wait
2、理解select与epoll之间的相同点和区别
int main()
{
int listenfd = socket(PF_INET, SOCK_STREAM, 0);
if(listenfd == -1) {
print_error("create");
}
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(8888);
servaddr.sin_addr.s_addr = INADDR_ANY;
if(bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1) {
print_error("bind");
}
if(listen(listenfd, 1) == -1) {
print_error("listen");
}
int epfd = epoll_create(1);
if(epfd == -1) {
printf("create epoll error: %s(errno: %d)\n", strerror(errno), errno);
exit(-1);
}
struct epoll_event events[POLL_SIZE] = {0};
struct epoll_event ev = {0};
ev.events = EPOLLIN;
ev.data.fd = listenfd;
if(epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev) == -1) {
printf("add epoll error: %s(errno: %d)\n", strerror(errno), errno);
exit(-1);
}
int nready = 0;
while(1) {
nready = epoll_wait(epfd, events, POLL_SIZE, 10);
if(nready > 0) {
int i = 0;
int eventfd;
for(; i<nready; i++) {
eventfd = events[i].data.fd;
if(eventfd == listenfd) {
int clientfd = handle_connect(listenfd);
ev.events = EPOLLIN;
ev.data.fd = clientfd;
epoll_ctl(epfd, EPOLL_CTL_ADD, clientfd, &ev);
}
else if(events[i].events & EPOLLIN) {
int ret = handle_request(eventfd);
if(ret == -1) {
ev.events = EPOLLIN;
ev.data.fd = eventfd;
epoll_ctl(epfd, EPOLL_CTL_DEL, eventfd, &ev);
close(eventfd);
}
}
}
}
}
close(listenfd);
return 0;
}