C++后端开发(2.1.2)——Reactor原理与实现

C++后端开发(2.1.2)——Reactor原理与实现

  • 0.简介
  • 1.reactor模型
  • 2.实现
    • 2.1定义结构
    • 2.2 分别实现事件的设置,添加和删除
    • 2.3分别实现事件建立连接、收消息、发消息的回调函数
    • 2.4 socket初始化
    • 2.5 reactor初始化与销毁
    • 2.6 reactor初始化后添加listen
    • 2.7 reactor循环,里面实现了回调函数
    • 2.8 main函数
  • 3.编译环境

0.简介

实现一个Reactor框架,Reactor是一种事件驱动框架,该框架下改变了select、poll和epoll对fd进行管理的思路转变成对读写事件进行管理,重点变成了事件。Reator逆置了事件处理流程,应用程序需要提供相应的接口并注册到Reactor上,在相应的时间发生,Reator将主动调用这些接口函数,即回调函数

1.reactor模型

reactor以epoll为底层,主要是对事件为基本单元进行处理,多个事件并发地交给服务器进行处理,服务器将传入的事件同步地分派给相关地处理函数,reactor处理事件模型如下所示

C++后端开发(2.1.2)——Reactor原理与实现_第1张图片

2.实现

2.1定义结构

首先分别定义了两个结构体,一个是事件 结构体ntyevent,一个是reactor结构体ntyreactor

ntyevent
* 该事件的fd
* 对应的事件类型events比如输入输出
* 需要传给回调函数的参数,一般传的是该事件所属reactor的指针void* arg
* 对应的回调函数指针 int (*callback)
* 事件是否创建的状态 status
* 事件消息的buffer
* 消息长度length
* 最后的运行时间last_active

ntyreactor(通过reactor来管理所有的事件)
* 该reactor的fd
* 该reactor内部的ntyevent数组==*events==(运行时通过epoll_wait取出所有存在内核的事件)

//事务结构体
//缓冲区长度
#define BUFFER_LENGTH 4096
// epoll中的事物数量
#define MAX_EPOLL_EVENT 1024
#define SERVER_PORT 8888
struct ntyevent
{
   
    int fd;     //事务的fd
    int events; // epoll events类型
    void *arg;  //需要传给回调函数的参数,一般传的是reactor的指针
    int (*callback)(int fd, int events, void *arg); //对应的回调函数
    int status; // 0:新建 1:已存在
    char buffer[BUFFER_LENGTH];
    int length;
    long last_active;
};
// reator使用的结构体
struct ntyreactor
{
   
    int epfd;                // reatctor的fd
    struct ntyevent *events; // reactor管理的基础单元
};

2.2 分别实现事件的设置,添加和删除

int recv_cb(int fd, int events, void *arg);
int send_cb(int fd, int events, void *arg);
int accpet_cb(int fd, int events, void *arg);
void nty_event_set(struct ntyevent *ev, int fd, NCALLBACK callback, void *arg);
int nty_event_add(int epfd, int events, struct ntyevent *ev);
int nty_event_del(int epfd, struct ntyevent *ev);

//设置ntyevent的参数
void nty_event_set(struct ntyevent *ev, int fd, NCALLBACK callback, void *arg)
{
   
    ev->fd = fd;
    ev->callback = callback;
    ev->events = 0;
    ev->arg = arg;
    ev->last_active = time(NULL);

    return;
}

//增加或修改
int nty_event_add(int epfd, int events, struct ntyevent *ev)
{
   
    //使用的是linux内核里的epoll
    struct epoll_event ep_ev = {
   0, {
   0}};
    //这一步非常关键传到联合体data的ptr里的是ntyevent指针
    ep_ev.data.ptr = ev;
    ep_ev.events = ev->events = events;
    //判断该事件是否已经添加过
    int op;
    if (ev->status == 1)
    {
   
        op = EPOLL_CTL_MOD;
    }
    else
    {
   
        op = EPOLL_CTL_ADD;
        ev->status = 1;
    }
    // epoll_ctl进行对应操作
    if (epoll_ctl(epfd, op, ev->fd, &ep_ev) < 0)
    {
   
        printf("event add failed [fd=%d], events[%d]\n", ev->fd, events);
        return -1;
    }
    return 0;
}

int nty_event_del(

你可能感兴趣的:(后端,网络编程,服务器,后端,c++)