非阻塞,et模型 epoll

来源:互联网 发布:每周开户数据 编辑:程序博客网 时间:2024/05/29 11:18
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/socket.h>#include <sys/epoll.h>#include <netinet/in.h>#include <unistd.h>#include <arpa/inet.h>#include <fcntl.h>#include <errno.h>#define MAX_EVENTS 100#define MAX_BUFFER_SIZE 10/*设置非阻塞*/int setNonBlock(int fd){int old_flag = fcntl(fd, F_GETFL);fcntl(fd, F_SETFL, old_flag | O_NONBLOCK);return old_flag;}/*添加到epoll池中*/void addfd_to_epoll(int epfd, int fd){struct epoll_event event;event.data.fd = fd;event.events = EPOLLIN | EPOLLET;setNonBlock(fd);epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &event);}void err_exit(char *msg){perror(msg);exit(1);}int create_socket(char *ip, int port){struct sockaddr_in addr;int sockfd, reuse = 1;memset(&addr, 0, sizeof(sockaddr_in));addr.sin_family = AF_INET;addr.sin_port = htons(port);if(inet_pton(PF_INET, ip, &addr.sin_addr) == -1){err_exit("inet_pton() error");}if((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1){err_exit("socket() error");}if(-1 == setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))){err_exit("setsockopt() error");}if(-1 == bind(sockfd, (struct sockaddr*)&addr, sizeof(addr))){err_exit("bind() error");}//待处理连接最大5if(-1 == listen(sockfd, 5)){err_exit("listen() error");}return sockfd;}void epoll_process(int epfd, struct epoll_event *events, int num, int listenfd){struct sockaddr addr;int newfd, confd;socklen_t len;for(int i = 0; i < num; ++i){newfd = events[i].data.fd;if(newfd == listenfd){confd = accept(listenfd, &addr, &len);addfd_to_epoll(epfd, confd);}else{printf("开始接受客户端%d数据 \n", newfd);//et的循环接受数据 char szBuf[MAX_BUFFER_SIZE + 1];while(1){memset(&szBuf, 0, sizeof(szBuf));int ret = recv(newfd, szBuf, MAX_BUFFER_SIZE, 0);if(ret == 0){printf("客户端主动关闭请求\n");close(newfd);break;}else if(ret == -1){if(errno == EAGAIN || errno == EWOULDBLOCK){printf("循环读取完了所有的数据 \n");break;}else if(104 == errno) //connetction reset by peer{printf("客户端主动关闭请求\n");}close(newfd);break;}else{printf("接受到数据%d字节,数据: %s\n", ret, szBuf);}}}}}int main(int argc, char** argv){if(argc < 3){fprintf(stderr, "usage:%s ip_address port_number\n", argv[0]);exit(0);}int listenfd, epfd;listenfd = create_socket(argv[1], atoi(argv[2]));epfd = epoll_create(100000);if(-1 == epfd) exit(-1);addfd_to_epoll(epfd, listenfd);struct epoll_event events[MAX_EVENTS + 1];while(1){int num = epoll_wait(epfd, events, MAX_EVENTS, 0);if(num == -1){err_exit("epoll_wait() error");}else{epoll_process(epfd, events, num, listenfd); }usleep(10);}close(listenfd);return 0;}

0 0