Linux高级I/O:Reactor反应堆模式 | Epoll ET模式


全文约 8696 字,预计阅读时长: 25分钟


在这里插入图片描述


Reactor反应堆模式

  • Reactor:负责检测关心的IO事件,当检测到IO事件时,分发给Handlers处理(对数据的读写处理+对数据的分析处理)。
  • epoll ET工作方式:只支持非阻塞IO文件。

简易的Reactor epoll ET TCP服务器

单进程基于ET非阻塞设计的一个Reactor模式+数据读写+数据分析。

socket封装

监听套接字的创建、绑定、监听、设置非阻塞I/O

#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <strings.h>
#include<fcntl.h>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;

namespace ns_sock
{
   
    enum
    {
   
        SOCK_ERR = 2,
        BIND_ERR,
        LISTEN_ERR
    };

    const int g_backlog = 5;

    struct sock_package
    {
   
        static int SockCreate()
        {
   
            int sock = socket(AF_INET, SOCK_STREAM, 0);
            if (sock < 0)
            {
   
                cerr << "socket  failed" << endl;
                exit(SOCK_ERR);
            }
            //设置可以立即重启绑定。
            int opt = 1;
            setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
            return sock;
        }
        static void Bind(const int &sock_fd, const uint16_t &port)
        {
   
            struct sockaddr_in local;
            bzero(&local, sizeof(local));
            local.sin_addr.s_addr = INADDR_ANY;
            local.sin_port = htons(port);
            local.sin_family = AF_INET;
            if (bind(sock_fd, (sockaddr *)&local, sizeof(local)) < 0)
            {
   
                cerr << "Bind Error" << endl;
                exit(BIND_ERR);
            }
        }
        static void Listen(const int &sock_fd)
        {
   
            if (listen(sock_fd, g_backlog) < 0)
            {
   
                cerr << "Listen Error" << endl;
                exit(LISTEN_ERR);
            }
        }
        static void set_noblock(int listen_sk)
        {
   
            int ret_sock = fcntl(listen_sk,F_GETFL);
            if(ret_sock<0)
            {
   
                cerr<<"fcntl error"<<endl;
                exit(5);
            }
            fcntl(listen_sk,F_SETFL,ret_sock | O_NONBLOCK);
        }
    };

}

epoll。hpp

一:epoll文件描述符的创建,往epoll文件描述里、添加需要关心的I/O文件 、以及关心的I/O文件的事件;检测事件的发生。

二:当前I/O文件的错误回调功能具有:哈希表删除当前的fd值,epoll_del从epoll红黑树中删除该fd节点;最后关闭fd。

三:检测到所有的异常事件发生时,都交付给当前I/O文件的错误回调处理。

四:当检测有事件就绪时应检测当前I/O文件的FD是否还存在。因为可能发送事件触发时,上一秒该文件有异常,从epoll中删除了。

五:具有一个可以让:当前I/O文件读取完毕后,构建发送报文时,可以修改当前该文件的关心事件的功能。因为读事件时一直需要关心的,写事件需要服务器返回数据时开启,发送完毕取消关心。sock文件描述符的反应堆指针,是为了后续可以使用其内部相关功能。

#pragma once
#include <iostream>
#include <sys/epoll.h>
#include <unordered_map>
#include <string>
#include <utility>
#include <unistd.h>

using namespace std;
namespace ns_reactor
{
   
    class reactor_sv;
    class sock_pack;
    typedef void (*sock_callback)(sock_pack &);//函数指针类型
    class sock_pack//sock_fd配套设施。
    {
   
    public
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值