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的回调函数

相关推荐
凡人叶枫2 分钟前
C++中输入、输出和文件操作详解(Linux实战版)| 从基础到项目落地,避坑指南
linux·服务器·c语言·开发语言·c++
CSDN_RTKLIB3 分钟前
使用三方库头文件未使用导出符号情景
c++
春日见14 分钟前
车辆动力学:前后轮车轴
java·开发语言·驱动开发·docker·计算机外设
锐意无限18 分钟前
Swift 扩展归纳--- UIView
开发语言·ios·swift
低代码布道师18 分钟前
Next.js 16 全栈实战(一):从零打造“教培管家”系统——环境与脚手架搭建
开发语言·javascript·ecmascript
念何架构之路36 分钟前
Go进阶之panic
开发语言·后端·golang
亓才孓40 分钟前
[Properties]写配置文件前,必须初始化Properties(引用变量没执行有效对象,调用方法会报空指针错误)
开发语言·python
傻乐u兔43 分钟前
C语言进阶————指针3
c语言·开发语言
两点王爷1 小时前
Java基础面试题——【Java语言特性】
java·开发语言
Swift社区1 小时前
Gunicorn 与 Uvicorn 部署 Python 后端详解
开发语言·python·gunicorn