eoll服务器
来源:互联网 发布:成都犀牛软件培训班 编辑:程序博客网 时间:2024/06/03 20:34
epoll实现(ET)
#include <stdio.h>#include <string.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/socket.h>#include <sys/types.h>#include <stdlib.h>#include <sys/epoll.h>#include <fcntl.h>#include <errno.h>#include <assert.h>#include <pthread.h>#define MAX_READY_EVENTS 64//将文件描述符设置为非阻塞的int setnonblocking(int fd){ int old_option = fcntl(fd, F_GETFL); int new_option = old_option|O_NONBLOCK; fcntl(fd, F_SETFL, new_option); return old_option;}//将文件描述符fd上的EPOLLIN注册到epollfd指示的epoll内核事件表中,参数enable_et指定是否对fd启用ET模式void addfd(int epollfd, int fd, int enable_et){ struct epoll_event event; event.data.fd = fd; event.events = EPOLLIN; if(enable_et) { event.events |= EPOLLET; } epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &event); setnonblocking(fd);}static void usage(const char* proc){ printf("Usage %s: [local_ip] [local_port]\n", proc);}int startup(const char* _ip, int _port){ int sock = socket(AF_INET, SOCK_STREAM, 0); if(sock < 0) { perror("sock"); return 2; } int opt = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); struct sockaddr_in local; local.sin_family = AF_INET; local.sin_port = htons(_port); local.sin_addr.s_addr = inet_addr(_ip); if(bind(sock, (struct sockaddr*)&local, sizeof(local)) < 0) { perror("bind"); return 3; } if(listen(sock, 10) < 0) { perror("listen"); return 4; } return sock;}int main(int argc, char* argv[]){ if(argc != 3) { usage(argv[0]); return 1; } int listen_sock = startup(argv[1], atoi(argv[2])); int epfd = epoll_create(256); if(epfd < 0) { perror("epoll_create"); return 5; } struct epoll_event ev; ev.events = EPOLLIN; ev.data.fd = listen_sock; if(epoll_ctl(epfd, EPOLL_CTL_ADD, listen_sock, &ev) < 0) { perror("epoll_ctl"); return 6; } int timeout = 1000; int nums = -1; struct epoll_event revs[MAX_READY_EVENTS]; while(1) { switch(nums = epoll_wait(epfd, revs, MAX_READY_EVENTS, /*timeout*/-1)) { case 0: { printf("timeout...\n"); } break; case -1: { perror("epolly_wait"); return 7; } break; default: { int i = 0; for(; i < nums; i++) { int fd = revs[i].data.fd; if((fd == listen_sock) && (revs[i].events == EPOLLIN)) { struct sockaddr_in client; socklen_t len = sizeof(client); int new_sock = accept(listen_sock, (struct sockaddr*)&client, &len); if(new_sock < 0) { perror("accept"); return 8; } printf("get new client: [%s:%d]\n",inet_ntoa(client.sin_addr), ntohs(client.sin_port)); struct epoll_event ev1; ev1.events = EPOLLIN; ev1.data.fd = new_sock; if(epoll_ctl(epfd, EPOLL_CTL_ADD, new_sock, &ev1) < 0) { perror("epoll_ctl"); return 9; } addfd(epfd, new_sock, 1);//开启ET模式 }// listen_sock can read else if((fd != listen_sock) && (revs[i].events & EPOLLIN)) { //ET模式下下面代码不会重复触发,所以我们循环读取数据 while(1) { char *buf[1024]; int s = read(fd, buf, sizeof(buf)-1); if(s < 0) { if((errno == EAGAIN) || (errno == EWOULDBLOCK)) { break; } close(fd); break; } else if(s == 0) { printf("client quit...\n"); close(fd); } else { buf[s] = 0; printf("client ####:%s", buf); } } }//other events can read else if((fd != listen_sock) && (revs[i].events & EPOLLOUT)) { char* msg = ""; write(fd, msg, strlen(msg)); close(fd); epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL); }//events can write }//for }//default break; } } return 0;}
阅读全文
0 0
- eoll服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 服务器
- 使用DroidPlugin实现模块化开发(主要说调用)
- MySQL运维之神奇的参数(终结篇)
- Codeforces822 A I'm bored with life
- 面试时如何阐释设计思路?
- Android Filter类
- eoll服务器
- 搭建亿万级别短信服务发送平台
- Stack Clash 漏洞正粉碎 Linux 防御危及 root 权限
- 最辛苦的生活其实是混吃等死
- JS伪数组
- ANDROID SUPPORT兼容包详解
- JDK的安装、配置及验证
- 准确率(Accuracy), 精确率(Precision), 召回率(Recall)和F1-Measure
- 深入Android源码系列(二) HOOK技术大作战