epoll 学习笔记
来源:互联网 发布:bandcamp 知乎 编辑:程序博客网 时间:2024/05/16 11:37
1 Epoll函数
首先看一下epoll的几个函数的介绍。
1.1 epoll_create函数
1.1.1 函数原型
/** * @brief 该函数生成一个epoll专用的文件描述符。它其实是在内核申请一空间,用来存放你想关注的socket fd上是否发生以及发生了什么事件。 * * @param size size就是你在这个epoll fd上能关注的最大socketfd数 * * @return 生成的文件描述符 */int epoll_create(int size);
1.1.2 函数实例
/* listener为socket文件描述符,kdpfd为epoll文件描述符 */int listener, kdpfd; struct sockaddr_in my_addr;/* 创建socket */ if ((listener =socket(PF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } bzero(&my_addr,sizeof(my_addr)); my_addr.sin_family = PF_INET; my_addr.sin_port = htons(PORT);my_addr.sin_addr.s_addr =INADDR_ANY;/* 绑定socket */ if (bind(listener, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) { perror("bind"); exit(1); } /*监听socket */ if (listen(listener, LISNUM)== -1) { perror("listen"); exit(1); }/* 以上初始化完成后,创建epoll 句柄,也可以先创建epoll句柄,再初始化socket */ kdpfd =epoll_create(MAXEPOLLSIZE);
1.2 epoll_ctl函数
1.2.1 函数原型
/** * @brief 该函数用于控制某个epoll文件描述符上的事件,可以注册事件,修改事件,删除事件。 * * @param epfd 由 epoll_create 生成的epoll专用的文件描述符 * @param op 要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修 改、EPOLL_CTL_DEL 删除 * @param fd 关联的文件描述符 * @param event 指向epoll_event的指针 * * @return 0 succ * -1 fail */int epoll_ctl(int epfd,int op,int fd,structepoll_event*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 events */ epoll_data_t data; /* User data variable */};
常用的事件类型:
EPOLLIN :表示对应的文件描述符可以读;
EPOLLOUT:表示对应的文件描述符可以写;
EPOLLPRI:表示对应的文件描述符有紧急的数据可读
EPOLLERR:表示对应的文件描述符发生错误;
EPOLLHUP:表示对应的文件描述符被挂断;
EPOLLET: 表示对应的文件描述符有事件发生;
1.2.2 函数实例
struct epoll_event ev; //设置要处理的事件类型 ev.events =EPOLLIN | EPOLLET; //设置与要处理的事件相关的文件描述符 ev.data.fd =listener; //注册epoll事件,将监听的socket加入epoll if (epoll_ctl(kdpfd,EPOLL_CTL_ADD, listener, &ev) < 0) { fprintf(stderr,"epoll set insertion error: fd=%d\n", listener); return -1; }
1.3 epoll_wait函数
1.3.1 函数原型
/** * @brief 该函数用于轮询I/O事件的发生 * * @param epfd 由epoll_create 生成的epoll专用的文件描述符 * @param events 用于回传代处理事件的数组 * @param maxevents 每次能处理的事件数 * @param timeout 等待I/O事件发生的超时值;-1相当于阻塞,0相当于非阻塞。一般用-1即可 * * @return >=0 返回发生事件数 * -1 错误 */int epoll_wait(int epfd,structepoll_event* events,int maxevents,int timeout);
1.3.2 函数实例
struct epoll_event events[MAXEPOLLSIZE];while (1) { /* 等待有事件发生 */ nfds =epoll_wait(kdpfd, events, curfds,-1); if (nfds == -1) { perror("epoll_wait"); break; } /* 处理所有事件 */ for (n = 0; n <nfds; ++n) { if (events[n].data.fd == listener) { new_fd = accept(listener, (struct sockaddr *)&their_addr,&sizeof(struct sockaddr_in)); if (new_fd < 0) { perror("accept"); continue; } else { printf("有连接来自于: %d:%d,分配的 socket为:%d\n", inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port), new_fd); } setnonblocking(new_fd); ev.events = EPOLLIN | EPOLLET; ev.data.fd = new_fd; if (epoll_ctl(kdpfd,EPOLL_CTL_ADD, new_fd, &ev) < 0) { fprintf(stderr,"把 socket '%d'加入 epoll失败!%s\n", new_fd, strerror(errno)); return -1; } curfds++; } else { ret= handle_message(events[n].data.fd); if (ret < 1&& errno != 11) { epoll_ctl(kdpfd, EPOLL_CTL_DEL, events[n].data.fd,&ev); curfds--; } } } } close(listener);
- epoll详解-epoll学习笔记
- epoll学习笔记
- epoll学习笔记
- epoll学习笔记
- epoll学习笔记
- epoll 学习笔记
- epoll学习笔记
- epoll学习笔记
- epoll学习笔记(转)
- epoll学习笔记
- epoll学习笔记
- Epoll学习笔记
- epoll学习笔记
- epoll学习笔记
- epoll 学习笔记
- epoll学习笔记
- epoll学习笔记
- epoll学习笔记
- openstack swift
- 基于ECLIPSE的HADOOP1.0应用开发环境配置
- linux shell中 出现select not found问题
- 手动 命令行打包 apk 示例
- 在visio的框图中如何加入公式
- epoll 学习笔记
- Spring mvc动态多数据源
- 自动登录SAP 系统 log in SAP without inputing password repeatly
- 论坛收集-
- Android MediaPlayer
- Oracle导出表(即DMP文件)的两种方法
- 获取系统名字及相关信息的函数
- Introduce SQL Server Compact Note
- JAVA里怎样对指定目录的文件按文件名排序