Epoll示例
来源:互联网 发布:汤敏的淘宝店网址 编辑:程序博客网 时间:2024/05/22 03:43
#include <iostream>#include <sys/socket.h>#include <sys/epoll.h>#include <netinet/in.h>#include <arpa/inet.h>#include <fcntl.h>#include <unistd.h>#include <strings.h>#include <string.h>#include <stdio.h>using namespace std;#define MAXLINE 32#define OPEN_MAX 100#define LISTENQ 20#define SERV_PORT 5555#define INFTIM 1000void setnonblocking(int sock){ int opts; opts = fcntl(sock, F_GETFL); if(opts < 0) { perror("fcntl(sock,GETFL)"); exit(1); } opts = opts | O_NONBLOCK; if(fcntl(sock, F_SETFL, opts) < 0) { perror("fcntl(sock,SETFL,opts)"); exit(1); }}int main(){/* 结构体epoll_event 被用于注册所感兴趣的事件和回传所发生待处理的事件,定义如下: typedef union epoll_data { void *ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t;//保存触发事件的某个文件描述符相关的数据 struct epoll_event { __uint32_t events; // epoll event epoll_data_t data; // User data variable }; 其中events表示感兴趣的事件和被触发的事件,可能的取值为: EPOLLIN :表示对应的文件描述符可以读; EPOLLOUT:表示对应的文件描述符可以写; EPOLLPRI: 表示对应的文件描述符有紧急的数可读; EPOLLERR:表示对应的文件描述符发生错误; EPOLLHUP:表示对应的文件描述符被挂断; EPOLLET: ET的epoll工作模式;*/ssize_t n;char line[MAXLINE];socklen_t clilen;struct epoll_event ev,events[20];int i,maxi,listenfd,connfd,sockfd,epfd,nfds;/*1、epoll_create函数 函数声明:int epoll_create(int size) 功能:该函数生成一个epoll专用的文件描述符,其中的参数是指定生成描述符的最大范围;*/epfd = epoll_create(256);struct sockaddr_in clientaddr;struct sockaddr_in serveraddr;listenfd = socket(AF_INET,SOCK_STREAM,0);//设置非阻塞setnonblocking(listenfd);/*2、epoll_ctl函数 函数声明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) 功能:用于控制某个文件描述符上的事件,可以注册事件,修改事件,删除事件。 @epfd:由 epoll_create 生成的epoll专用的文件描述符; @op:要进行的操作,EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修改、EPOLL_CTL_DEL 删除; @fd:关联的文件描述符; @event:指向epoll_event的指针; 成功:0;失败:-1*/ev.data.fd = listenfd;ev.events = EPOLLIN | EPOLLET;epoll_ctl(epfd,EPOLL_CTL_ADD,listenfd,&ev);//服务器地址绑定bzero(&serveraddr,sizeof(serveraddr));serveraddr.sin_family = AF_INET;serveraddr.sin_addr.s_addr = INADDR_ANY;serveraddr.sin_port = htons(1234);bind(listenfd,(const sockaddr*)&serveraddr,sizeof(serveraddr));listen(listenfd,LISTENQ);while(true) { /* 3、epoll_wait函数 函数声明:int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout) 功能:该函数用于轮询I/O事件的发生; @epfd:由epoll_create 生成的epoll专用的文件描述符; @epoll_event:用于回传代处理事件的数组; @maxevents:每次能处理的事件数; @timeout:等待I/O事件发生的超时值; 成功:返回发生的事件数;失败:-1 */ nfds = epoll_wait(epfd,events,20,500); for(i = 0;i < nfds;i ++) { if(events[i].data.fd == listenfd) {//如果新监测到一个SOCKET用户连接到了绑定的SOCKET端口,建立新的连接。 connfd = accept(listenfd,(sockaddr*)&clientaddr,&clilen); if(connfd < 0){ perror("connfd<0"); return -1; } //设置非阻塞 setnonblocking(listenfd); printf("ip client:%s\n",inet_ntoa(clientaddr.sin_addr)); ev.data.fd = connfd; ev.events = EPOLLIN | EPOLLET; epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); }else if (events[i].events & EPOLLIN) {//如果是已经连接的用户,并且收到数据,那么进行读入。 if ((sockfd = events[i].data.fd) < 0) continue;//确定连接用户存在 if ((n = read(sockfd,line,MAXLINE))< 0){ if(errno == ECONNRESET) { close(sockfd); events[i].data.fd = -1; } else cout<<"readline error"<<endl; }else if (0 == n){ close(sockfd); events[i].data.fd = -1; } printf("Data ==:%s\n",line); ev.data.fd = sockfd;//修改sockfd事件为EPOLLOUT ev.events = EPOLLOUT | EPOLLET; epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); } else if (events[i].events & EPOLLOUT) { printf("send data to client\n"); sockfd = events[i].data.fd; write(sockfd,"hello client",n); ev.data.fd =sockfd; ev.events = EPOLLIN | EPOLLET; epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); } }}return 0;}
阅读全文
0 0
- epoll示例
- epoll示例
- epoll示例
- epoll示例
- epoll示例
- epoll示例
- epoll 示例
- Epoll示例
- epoll服务器示例
- Epoll 使用示例
- epoll使用示例
- epoll 入门示例
- 关于epoll的示例
- Epoll使用示例
- Epoll示例代码
- linux epoll示例
- epoll 示例代码
- ace epoll使用源码示例
- React Native JDK自带工具keytool生成ssl证书
- Httpclient核心架构设计
- Android JNI的使用 显示Hello Word
- ubuntu14.04安装cuda8.0
- WTL-编译出错01--CVTRES : fatal error CVT1100: 资源重复。类型: MANIFEST,名称: 1,语言: 0x0409
- Epoll示例
- React-native windows 安卓 打包
- 网络层与路由器
- sar 找出系统瓶颈的利器
- spring实现dubbo服务
- NGUI UI Localize本地化(语言切换)
- [JAVA学习笔记-82]Thread states in JAVA
- python爬取5442网站图片
- 1154 能量项链