epoll反应堆
epoll 原来:socket、bind、listen、— epoll_create创建监听红黑树 —返回epfd — epoll_ctl()向树上添加一个监听fd — while(1) — epoll_wait()监听 ---- 对应监听fd有事情产生 ---- 返回监听满足数组 —判断返回数组元素 — lfd满足 — accept ---- cfd满足 ---- read() ----小写–》大写 ---- write回去
epoll 反应堆模型:epoll ET模式 + 非阻塞,轮询 + void *ptr
反应堆:不但要监听cfd的读事件,还要监听cfd的写事件
socket、bind、listen、— epoll_create创建监听红黑树 —返回epfd — epoll_ctl()向树上添加一个监听fd — while(1) — epoll_wait()监听 ---- 对应监听fd有事情产生 ---- 返回监听满足数组 —判断返回数组元素 — lfd满足 —accept — cfd满足 — read() — 小》大 — cfd 从监听红黑树摘下 — EPOLLOUT ----回调函数 — epoll_ctl() —EPOLL_CTL_ADD重新放到红黑树上监听写事件 ---- 等待epoll_wait返回 — 说明cfd可写 — write回去 — cfd从监听红黑树上摘下 — EPPOLLIN —epoll_ctl() ----EPOLL_CTL_ADD重新放到红黑树上监听读事件 ---- 等待epoll_wait返回。。。
eventset()函数:
设置回调函数: lfd ---> acceptconn()
cfd ---> recvdata()
cfd ---> senddata()
eventadd()函数:
将一个fd,添加到监听红黑树,设置监听读事件,还有写事件
网络编程中: read ------ recv
write ------ send
/*
*epoll基于非阻塞I/O事件驱动
*/
#include <stdio.h>
#include <sys/socket.h>
#include <sys/epoll.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define MAX_EVENTS 1024 //监听上限数
#define BUFLEN 4096
#define SERV_PORT 8080
void recvdata(int fd, int events, void *arg);
void senddata(int fd, int events, void *arg);
/* 描述就绪文件描述符相关信息 */
struct myevent_s {
int fd; //要监听的文件描述符
int events; //对应的监听事件
void *arg; //泛型参数
void (*call_back)(int fd, int events, void *arg); //回调函数
int status; //是否在监听:1->在红黑树上(监听), 0->不在(不监听)
char buf[BUFLEN];
int len;
long last_active; //记录每次加入红黑树 g_efd 的时间值
};
int g_efd; //全局变量, 保存epoll_create返回的文件描述符
struct myevent_s g_events[MAX_EVENTS+1]; //自定义结构体类型数组. +1-->listen fd
/*将结构体 myevent_s 成员变量 初始化*/
void eventset(struct myevent_s *ev, int fd, void (*call_back)(int, int, void *), void *arg)
{
ev->fd = fd;
ev->call_back = call_back;
ev->events = 0;
ev->arg = arg;
ev->status = 0;
//memset(ev->buf, 0, sizeof(ev->buf));
//ev->len = 0;
ev->last_active = time(NULL); //调用eventset函数的时间
return;
}
/* 向 epoll监听的红黑树 添加一个 文件描述符 */
void eventadd(int efd, int events, struct myevent_s *ev)
{
struct epoll_event epv = {
0, {
0}};
int op;
epv.data.ptr = ev;
epv.events = ev->events = events