Reactor反应堆模式

reactor 反应堆模式

运行结果:

补充:

1、通信套接字

cpp 复制代码
    static void HandleRequest(Connection* conn)
    {
        string s;
        while(DeLenHeader(conn->_inbuffer, &s))
        {
            Request req;
            req.DeSerialize(s);

            int result;
            switch(req._op)
            {
            case '+':
                result= req._x+ req._y;
                break;
            case '-':
                result= req._x- req._y;
                break;
            case '/':
                result= req._x/ req._y;
                break;
            case '*':
                result= req._x* req._y;
                break;
            }
            
            Response rsp(result, 0);

            string sen= rsp.Serialize();
            EnLenHeader(sen);

            conn->_outbuffer+= sen;
        }

        if(!conn->_outbuffer.empty())
        {
            conn->_server->ModifyEvents(conn->_fd, EPOLLIN | EPOLLOUT| EPOLLET);
        }
    }

    static void HandleRead(Connection* conn)
    {
        std::string& inbuffer= conn->_inbuffer;
        char buffer[1024];

        while(1)
        {
            int n= read(conn->_fd, buffer, sizeof(buffer)-1);
            if(n> 0)
            {
                buffer[n]= 0;
                inbuffer+= buffer;
            }
            else if(n== 0)
            {
                conn->_server->DelConnection(conn);
                conn->_server->DelEvents(conn->_fd);
                close(conn->_fd);
                delete conn;
                return;
            }
            else if(n== -1 && errno== EAGAIN)
            {
                break;
            }
        }

        HandleRequest(conn);
    }

    static void HandleWrite(Connection* conn)
    {
        while(1)
        {
            int n= write(conn->_fd, conn->_outbuffer.c_str(), conn->_outbuffer.size());//参数传的是要写的数据,返回值是实际写入发送缓冲区的数据字节数

            if(n> 0)
            {
                conn->_outbuffer.erase(0, n);
                if(conn->_outbuffer.empty())
                {
                    break;
                }
            }
            else if(n==-1 && errno== EAGAIN)
            {
                break;
            }
        }

        //走到这里,可能是数据全部写进了发送缓冲区,也可能是发送缓冲区满了
        //如果是因为全写进了发送缓冲区,那么就不需要监控可写事件了,如果是发送缓冲区满了,那就还得监控,等发送缓冲区的数据由内核发送出去后,会执行ep_poll_callback,将struct epitem加进就绪队列里
        if(conn->_outbuffer.empty())
        {
            conn->_server->ModifyEvents(conn->_fd, EPOLLIN |EPOLLET);
        }
    }

如果我们往发送缓冲区中一次写很多数据,那么很可能最后只能写入一部分,然后write会返回写入发送缓冲区的数据的字节数,如果写是非阻塞的,那么当发送缓冲区满了的时候,write会直接返回-1,设置errno为EAGAIN

上面的代码中,当对接受缓冲区中的数据接收并处理过之后,会将结果数据保存在另一个缓冲区中,然后启动可写事件监控,当结果数据没了之后,那就关闭可写事件监控

2、epoll_ctl

epoll_ctl有三种操作

  • EPOLL_CTL_ADD :用于添加新的文件描述符,如果已有对应文件描述符则添加失败

  • EPOLL_CTL_MOD :用于修改已监控文件描述符的事件(覆盖式)

  • EPOLL_CTL_DEL :用于移除文件描述符的监控

相关推荐
上海蓝色星球6 小时前
迈向智慧电网新纪元:上海蓝色星球数字孪生变电主子站系统
运维·数据库
南棱笑笑生7 小时前
20251217给飞凌OK3588-C开发板适配Rockchip原厂的Buildroot【linux-5.10】后调通ov5645【只能预览】
linux·c语言·开发语言·rockchip
爬山算法8 小时前
Netty(10)Netty的粘包和拆包问题是什么?如何解决它们?
服务器·网络·tcp/ip
Sleepy MargulisItG8 小时前
【Linux网络编程】应用层协议:HTTP协议
linux·服务器·网络·http
logic_58 小时前
静态路由配置
运维·服务器·网络
G31135422738 小时前
Linux 内核设计中的核心思想与架构原则
linux·架构·php
zhuzewennamoamtf9 小时前
Linux内核platform抽象、数据结构、内核匹配机制
linux·运维·数据结构
门思科技9 小时前
企业级 LoRaWAN 网关远程运维方案对比:VPN 与 NPS FRP 的技术与安全差异分析
运维·网络·安全
云和数据.ChenGuang9 小时前
Deepseek 持续迭代的模型
运维·运维技术·数据库运维工程师·运维教程
物联网软硬件开发-轨物科技9 小时前
【轨物方案】聚焦锯床设备智能化升级,打造工业互联网新范式
运维·科技·物联网