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

相关推荐
天若有情6731 天前
程序员原创|借鉴JS事件冒泡,根治电脑文件混乱的“冒泡整理法”
开发语言·javascript·windows·ecmascript·电脑·办公·日常
墨染千千秋1 天前
C++函数的使用以及主函数
c++
特种加菲猫1 天前
继承,一场跨越时空的对话
开发语言·c++
WBluuue1 天前
Codeforces 1093 Div2(ABCD1D2)
c++·算法
FYKJ_20101 天前
springboot校园兼职平台--附源码02041
java·javascript·spring boot·python·eclipse·django·php
玩转单片机与嵌入式1 天前
玩转边缘AI(TInyML):需要掌握的C++知识汇总!
开发语言·c++·人工智能
历程里程碑1 天前
4 Git远程协作:从零开始,玩转仓库关联与代码同步(带实操代码讲解)
大数据·c++·git·elasticsearch·搜索引擎·gitee·github
茉莉玫瑰花茶1 天前
Qt 信号与槽 [ 1 ]
开发语言·数据库·qt
汉克老师1 天前
GESP5级C++考试语法知识(贪心算法(一)课堂例题精讲)
c++·贪心算法·gesp5级·gesp五级·贪心规律