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

相关推荐
java1234_小锋5 分钟前
[免费]基于Python的Flask酒店客房管理系统【论文+源码+SQL脚本】
开发语言·人工智能·python·flask·酒店客房
bubiyoushang88818 分钟前
使用MATLAB计算梁单元的刚度矩阵和质量矩阵
开发语言·matlab·矩阵
三掌柜66632 分钟前
C++ 零基础入门与冒泡排序深度实现
java·开发语言·c++
laocaibulao36 分钟前
mac电脑composer命令如何指定PHP版本
macos·php·composer
Yyyy48241 分钟前
标签Labels、Scheduler:调度器、k8s污点与容忍度
开发语言·kubernetes
来来走走43 分钟前
Android开发(Kotlin) 扩展函数和运算符重载
android·开发语言·kotlin
zz-zjx1 小时前
云原生LVS+Keepalived高可用方案(二)
开发语言·php·lvs
wuwu_q1 小时前
用通俗易懂 + Android 开发实战的方式,详细讲解 Kotlin Flow 中的 retryWhen 操作符
android·开发语言·kotlin
沐怡旸1 小时前
【穿越Effective C++】条款15:在资源管理类中提供对原始资源的访问——封装与兼容性的平衡艺术
c++·面试
网络精创大傻1 小时前
PHP 与 Node.js:实际性能对比
开发语言·node.js·php