c++造轮子之REACTOR实战


本文实现的为单reactor 多线程(base)


非核心库

InetAddress

这个库简单而言 无疑是设置ip地址和端口

cpp 复制代码
class InetAddress
{
public:
    struct sockaddr_in addr;
    socklen_t addr_len;
    InetAddress();
    InetAddress(const char* ip, uint16_t port);
    ~InetAddress();
};

具体而言:

  • InetAddress(const char* ip, uint16_t port); 这个无疑是bind函数
  • InetAddress(); 这个无疑是accept函数 (connect 客户端 函数将自己系统分配ip和端口)

socket库

这个库实现的网络的绑定

cpp 复制代码
class InetAddress;
class Socket
{
private:
    int fd;
public:
    Socket();
    Socket(int);
    ~Socket();

    void bind(InetAddress*);
    void listen();
    void setnonblocking();

    int accept(InetAddress*);

    int getFd();
};

Epoll库和Channel库

实现io复用以及文件描述符将由channel替代(ev.data.ptr 决定)

复制代码
class Epoll
{
private:
    int epfd;
    struct epoll_event *events;
public:
    Epoll();
    ~Epoll();

    void addFd(int fd, uint32_t op);
    void updateChannel(Channel*);
    // std::vector<epoll_event> poll(int timeout = -1);
    std::vector<Channel*> poll(int timeout = -1);
};
  • epfd 为注册事件表返回的文件操作符
  • event :这个其实是等待序列 (内部用new方法实现了)(思考堆和栈的容量大小就知道了)
  • 这个addfd和updateChannel内部都实现了注册事件组
  • poll函数 返回了一个就绪vector 即检测的channel 基于事件检测 (把相应的文件符对应的Channel放入数组 方便操作)
cpp 复制代码
class EventLoop;
class Channel
{
private:
    EventLoop *loop;
    int fd;
    uint32_t events;
    uint32_t revents;
    bool inEpoll;
    std::function<void()> callback;
public:
    Channel(EventLoop *_loop, int _fd);
    ~Channel();

    void handleEvent();
    void enableReading();

    int getFd();
    uint32_t getEvents();
    uint32_t getRevents();
    bool getInEpoll();
    void setInEpoll();

    // void setEvents(uint32_t);
    void setRevents(uint32_t);
    void setCallback(std::function<void()>);
};
  • Eventloop:reactor中事件检测(即epoll_wait)
  • fd:相应的文件操作符
  • events:events表示希望监听这个文件描述符的哪些事件
  • uint32_t revents;//文件描述符正在发生的事件
  • bool inEpoll;//当前的channel是否在事件表(那个红黑树)
  • std::function<void()> callback; 这个也可说是回调函数(但是会等待执行)

核心库

EventLoop库

这个就是reactor中的事件驱动的原理

复制代码
class Epoll;
class Channel;
class EventLoop
{
private:
    Epoll *ep;
    bool quit;
public:
    EventLoop();
    ~EventLoop();

    void loop();
    void updateChannel(Channel*);
};
cpp 复制代码
void EventLoop::loop(){
    while(!quit){
    std::vector<Channel*> chs;
        chs = ep->poll();
        for(auto it = chs.begin(); it != chs.end(); ++it){
            (*it)->handleEvent();
        }
    }
}

工作原理:首先loop启动,epoll_wait不断的查询就绪的事件并返回就绪的channel.

Server库

cpp 复制代码
class EventLoop;
class Socket;
class Server
{
private:
  EventLoop *loop;
public:
  Server(EventLoop*);
  ~Server();

  void handleReadEvent(int);
  void newConnection(Socket *serv_sock);
};

这个库然后根据连接还是业务处理(echo函数)进行调用channel的回调函数

相关推荐
mftang10 分钟前
Python 字符串拼接成字节详解
开发语言·python
jasligea32 分钟前
构建个人智能助手
开发语言·python·自然语言处理
kokunka35 分钟前
【源码+注释】纯C++小游戏开发之射击小球游戏
开发语言·c++·游戏
汉堡包0011 小时前
【网安基础】--内网代理转发基本流程(正向与反向代理)
安全·web安全·php
云栖梦泽1 小时前
易语言开发从入门到精通:补充篇·网络编程进阶+实用爬虫开发·API集成·代理IP配置·异步请求·防封禁优化
开发语言
java1234_小锋2 小时前
Java高频面试题:SpringBoot为什么要禁止循环依赖?
java·开发语言·面试
铅笔侠_小龙虾2 小时前
Flutter Demo
开发语言·javascript·flutter
2501_944525542 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 账户详情页面
android·java·开发语言·前端·javascript·flutter
福大大架构师每日一题2 小时前
ComfyUI v0.11.1正式发布:新增开发者专属节点支持、API节点强化、Python 3.14兼容性更新等全方位优化!
开发语言·python
wangdaoyin20102 小时前
若依vue2前后端分离集成flowable
开发语言·前端·javascript