epoll_wait 。。 傷城~ 2022-08-14 01:45 186阅读 0赞 /********************************* * mkfifo p1 p2 * cat > p1 * cat > p2 *FileName: epoll_wait.c *Author : Dai *Version : 1 *Date : 2014.09.19 *Description: 用epoll_wait监听多个管道,管道中有内容就读出 (1)epoll_creat()创建一个句柄 *Note : 打开一个文件用非阻塞方式,不然会阻塞到read上, 而我们要求用epoll_wait()阻塞到epoll_wait()上 *********************************/ #include <stdio.h> #include <sys/epoll.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> struct epoll_event env; int main(void) { int fd1, fd2; if((fd1 = open("p1", O_RDONLY|O_NONBLOCK)) == -1){ perror("open p1 fail\n"); exit(-1); } if((fd2 = open("p2", O_RDONLY|O_NONBLOCK)) == -1){ perror("open p2 fail\n"); exit(-1); } int epoll_fd = epoll_create(1); if(epoll_fd == -1) perror("epoll create fail\n"); env.data.fd = fd1; env.events = EPOLLIN|EPOLLET; if((epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd1, &env)) == -1) perror("epoll_ctl p1 fail\n"); env.data.fd = fd2; env.events = EPOLLIN | EPOLLET; if((epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd2, &env)) == -1) perror("epoll_ctl p2 fail\n"); while(1){ char buf[32]; epoll_wait(epoll_fd, &env, 1, -1); int fd = env.data.fd; int len; while((len = (read(fd, buf, 32))) > 0) buf[len] = '\0'; printf("get %s from %d\n", buf, fd); } return 0; } \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* /***************************************** *Discription:用socket实现远程登录访问 用epoll_wait实现并发 两个端口进行通信 *socket 产生用于监听的描述符 bind 绑定地址和端口 listen 把套接字设为被动 accept()用于产生和客户机进行交 互的文件描述符 * * * * * *********************************/ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> //inet_ntop() #include <sys/epoll.h> #define SERV_port 8000 //端口号 #define max_r 100 //存取从客户端读过来的空间 #define max_ep 10 //从内核可以处理事件集合的大小 char buf_f[1024]; int flag_fd[100]; int f_fd; int main(void) { int listenfd, connfd; char buf[100]; char buf1[100]; int r_len; char str[INET_ADDRSTRLEN]; //。。。。。。。 struct sockaddr_in servaddr, cliaddr; int ep_fd, cur_ep, accept_Count = 0; //ep_fd创建的句柄用于处理wait的epoll文件描述符 cur_ep用于记录当前epoll_wait监听事件的个数 int nfds, i, j; //epoll_wait返回的处理事件的个数 struct epoll_event ep_env; //用于注册事件 struct epoll_event events[max_ep];//用于回传要处理的事件 listenfd = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(SERV_port); if(bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) == -1){ perror("bind fail\n"); } if(listen(listenfd, 20) == -1){ perror("listen fail\n"); } printf("now we can accept connections\n"); //创建epoll句柄 并把监听socket加入epoll队列 if((ep_fd = epoll_create(1)) == -1){ perror("epoll_create fail\n"); exit(-1); } memset(flag_fd, 0, sizeof(flag_fd)); ep_env.data.fd = listenfd; ep_env.events = EPOLLIN | EPOLLET; if((epoll_ctl(ep_fd, EPOLL_CTL_ADD, listenfd, &ep_env)) == -1){ perror("epoll_ctl fail\n"); } //把服务器标准输入加入epoll队列 ep_env.data.fd = STDIN_FILENO; ep_env.events = EPOLLIN | EPOLLET; if((epoll_ctl(ep_fd, EPOLL_CTL_ADD, STDIN_FILENO, &ep_env)) == -1){ perror("epoll_ctl fail\n"); } flag_fd[listenfd] = 1; flag_fd[STDIN_FILENO] = 1; printf("epoll_server start server port:%d\n", SERV_port); cur_ep = 2; while(1){ nfds = epoll_wait(ep_fd, events, cur_ep, -1); for(i = 0; i < nfds; i++){ if(events[i].data.fd == listenfd){ int cliaddr_len = sizeof(cliaddr); connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len); sprintf(buf, "accept from %s at port %d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port); printf("%d:%s", ++accept_Count, buf); ep_env.events = EPOLLIN | EPOLLET; ep_env.data.fd = connfd; epoll_ctl(ep_fd, EPOLL_CTL_ADD, connfd, &ep_env); flag_fd[connfd] = 1; cur_ep++; continue; } else if(events[i].data.fd == STDIN_FILENO){ if(handle(events[i].data.fd, connfd) < 0) { epoll_ctl(ep_fd, EPOLL_CTL_DEL, j, &ep_env); close(events[i].data.fd); cur_ep--; flag_fd[events[i].data.fd] = 0; } } else{ if(handle(events[i].data.fd, STDIN_FILENO) < 0){ epoll_ctl(ep_fd, EPOLL_CTL_DEL, connfd, &ep_env); close(events[i].data.fd); cur_ep--; flag_fd[events[i].data.fd] = 0; } } } /* int cliaddr_len = sizeof(cliaddr); while((r_len = read(connfd, buf, max_r))){ printf("received from %s at port %d\n", inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)), ntohs(cliaddr.sin_port)); write(connfd, buf, r_len); }*/ } close(listenfd); return 0; } //从src复制到dest int handle(int src, int dest) { int nread; int j; char buf[1024]; nread = read(src, buf, 1024); if(nread == 0){ printf("client close the connection\n"); return -1; } if(nread < 0){ perror("read error"); return -1; } for(j = 0; j < 100; j++) if(j != 3 && j != src && flag_fd[j] == 1) write(j, buf, nread); return 0; } \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\* #include <unistd.h> #include <sys/types.h> /* basic system data types */ #include <sys/socket.h> /* basic socket definitions */ #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */ #include <arpa/inet.h> /* inet(3) functions */ #include <sys/epoll.h> /* epoll function */ #include <fcntl.h> /* nonblocking */ #include <sys/resource.h> /*setrlimit */ #include <stdlib.h> #include <errno.h> #include <stdio.h> #include <string.h> #define MAXEPOLLSIZE 10 #define MAXLINE 10240 int handle(int connfd); int main(int argc, char **argv) { int servPort = 8000; int listenfd, connfd, kdpfd, nfds, n, nread; int curfds,acceptCount = 0; struct sockaddr_in servaddr, cliaddr; socklen_t socklen = sizeof(struct sockaddr_in); struct epoll_event ev; struct epoll_event events[MAXEPOLLSIZE]; char buf[MAXLINE]; bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl (INADDR_ANY); servaddr.sin_port = htons (servPort); listenfd = socket(AF_INET, SOCK_STREAM, 0); int opt = 1; setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(struct sockaddr)) == -1) { perror("bind error"); return -1; } listen(listenfd, 10); /* 创建 epoll 句柄,把监听 socket 加入到 epoll 集合里 */ kdpfd = epoll_create(MAXEPOLLSIZE); ev.events = EPOLLIN | EPOLLET; ev.data.fd = listenfd; epoll_ctl(kdpfd, EPOLL_CTL_ADD, listenfd, &ev); curfds = 1; printf("epollserver startup,port %d\n", servPort); for (;;) { /* 等待有事件发生 */ nfds = epoll_wait(kdpfd, events, curfds, -1); /* 处理所有事件 */ for (n = 0; n < nfds; ++n) { if (events[n].data.fd == listenfd) { connfd = accept(listenfd, (struct sockaddr *)&cliaddr,&socklen); sprintf(buf, "accept form %s:%d\n", inet_ntoa(cliaddr.sin_addr), cliaddr.sin_port); printf("%d:%s", ++acceptCount, buf); ev.events = EPOLLIN | EPOLLET; ev.data.fd = connfd; epoll_ctl(kdpfd, EPOLL_CTL_ADD, connfd, &ev); curfds++; continue; } // 处理客户端请求 if (handle(events[n].data.fd) < 0) { epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,&ev); close(events[n].data.fd); curfds--; } } } close(listenfd); return 0; } int handle(int connfd) { int nread; char buf[MAXLINE]; nread = read(connfd, buf, MAXLINE);//读取客户端socket流 if (nread == 0) { printf("client close the connection\n"); return -1; } if (nread < 0) { perror("read error"); return -1; } write(connfd, buf, nread);//响应客户端 return 0; }
还没有评论,来说两句吧...