基于epoll的Reactor模型

一、代码展示

1、主函数 main.cc(第一级别)

先控制台获取服务器的端口号,绑定端口号IP地址。PackageParse作为报文解析并发送接收报文的中间类,Listener是服务器的监听套接字,HandlerConnection是连接套接字,用于和业务结合,所以绑定方法PackageParse::Excute,Reactor是事件派发器,里面会有两种套接字的读写事件初始化和循环检测epoll读写事件就绪并处理。初始化完成就要开始绑定两种套接字的读写方法。监听套接字只要关心读方法(有新连接到来就是监听套接字的读事件就绪)普通套接字需要有读写事件和处理异常事件方法。最后先添加监听套接字,开始任务派发。

2、套接字封装 Connection.hpp (第二级别)

从现在开始只有连接的概念,没有单独一个套接字的概念,也是为例方便管理,引入连接类。一个套接字我们给他配备了单独的两个缓冲区(输入输出缓冲区)_outbufffer, _inbuffer,每一个套接字对应的处理读写事件和异常的方法_handler_recver, _handler_sender, _handler_excepter, 还有回指向Reactor对象的指针(让两者相互指向)_R,套接字的类型_type,套接字的关心事件_events,最后是连接套接字的客户端信息_addr

类Connection的工作就是处理好一个连接的信息,不考虑管理所有连接。包括设置三个方法,关心事件,回指指针,连接属性,绑定信息和处理缓冲区,添加输入输出缓冲区,配合_handler_sender删除输出缓冲区内容。

3、连接管理事件派发容器 Reactor.hpp (第二级别)

作为最底层直接与epoll打交道的容器,需要利用好Connection连接类来管理一个个的套接字。还有一个任务就是派发任务给一个个的连接。

任务一:管理套接字,用到了哈希表_connections,一个sockfd对应一个Connection对象,四个方法(是上层自己另写的,对应两种套接字不同的事件处理方法,之后展示)用于初始化并管理连接。

函数AddConnection给我传文件描述符,事件,客户端信息和连接类型,我来帮你用epoll管理连接。先设置Connection对象属性,然后把特定文件描述符所关心的特定事件交给epoll,最后添加给哈希表_connections

函数EnableConnectionReadWrite开启一个连接对读写事件的关心,把特定文件描述符所关心的特定事件交给epoll

函数DelConnection删除一个连接,先在内核移除sockfd关心(因为epoll要求文件描述符要正常),再一旦出异常sockfd要关闭,最后移除_connections

任务二:事件派发,用到了封装的epoll类和读取就绪事件的revents事件缓冲区。

函数LoopOnce是一次事件派发逻辑,一开始等待事件就绪,读到revents里面就绪的事件后循环处理就绪事件。先拿到文件描述符和对应的就绪事件,然后读事件就续就调用对应文件描述符对应连接里面的接收函数,写事件就续就调用对应文件描述符对应连接里面的发送函数。最后为了统一处理异常,如果出错依然改成读写事件就绪,再读写事件里面统一处理异常。

函数Dispatcher就是main.cc里面调用的函数,进行循环调用LoopOnce即可完成事件派发。

4、管理epoll类 Epoller.hpp (第二级别)

用于管理创建好的epfd,由于管理IO的方式有很多,有select, poll, epoll等,所以用一个基类Multiplex表示管理IO的类,子类封装了epoll方式。主要工作:添加,修改,等待,删除特定文件描述符的特定事件。

在构造函数时就要创建epfd,然后就是用原生接口实现上述四种功能。

5、监听套接字类 Listener.hpp (第三级别)

主要工作:构造函数初始化监听套接字,实现监听套接字的获取新连接功能。

函数Accepter在ET模式下要循环获取连接的文件描述符,新连接要调用AddConnection托管给Reactor

6、普通套接字类 HandlerConnection.hpp (第三级别)

普通的连接套接字已经与业务相结合了,所以有一个字段_process是业务函数。

主要工作是处理读事件,写事件和异常事件。

补充知识:多路转接如何正确处理写事件?

多进程和多线程的写入更简单,可以阻塞式写入。

在多路转接中,读事件就绪意味着输入缓冲区有数据或新连接到来,写事件就绪意味着不关心数据,关心发送缓冲区中有无空间写入,有空间就是就绪。

把一个sockfd托管给select, poll, epoll代表当前sockfd事件未就绪。

一个新的sockfd输入输出缓冲区默认为空。

从上述客观事实得出两个结论:

(1)sockfd新建的情况下,默认读事件不就绪,注意ET模式下每次还要读完输入缓冲区,所以正常情况下输入缓冲区一直为空,读事件一直不就绪,所以要常开启读事件关心(对应到函数HandlerRecver就是结束时不要关闭读事件的关心)。

(2)sockfd新建的情况下,默认写事件就绪。所以一开始不关心EPOLLOUT事件,只有当输出缓冲区满了&&还有数据要写入,才开启写事件关心,之后剩余的数据回epoll自动发送(当写事件就绪了LoopOnce自己会调用_handler_sender函数)

细节:

(1)如果一开始直接设EPOLLOUT,epoll就会大量就绪。

(2)未来发完了数据,一定要关闭EPOLLOUT关心。

(3)如果缓冲区没满,数据也发完了,不用开启EPOLLOUT关心。

(4)如果设置EPOLLOUT,epoll对EPOLLOUT的首次关心回默认就绪一次。

7、服务器与客户端报文IO的中间人 PackageParse.hpp (第四级别)

有一个业务字段用于调用业务处理函数。

主要工作:从输入缓冲区中读取客户端的请求数据,再反序列化得到请求对象,通过最上层的业务函数得到应答对象,再序列化应答对象,构建应答报文之后再发送回输出缓冲区,最后激活写事件关心发送应答报文。

8、一个简单的网络计算器业务 NetCal.hpp (第四级别)

主要工作:接收请求对象,返回应答对象。

9、自定义tcp协议 Protocol.hpp (第四级别)

主要工作:供PackageParse.hpp和NetCal.hpp通信使用,最上层网络通信一定要有协议支持。

首先要有添加报头和解析完整报文两个全局函数,用于报文的封装和解析。然后商量请求报文格式和应答报文格式,所以设计请求类和应答类,里面都会有序列化和反序列化。序列化就是把类里面的对象数据变成报文,反序列化就是把报文里面的数据提取成对象数据储存。

最后可以封装两个创建对象的工厂,上层只能用工厂创建请求应答对象。

10、三个辅助类 Socket.hpp inetAddr.hpp log.hpp

二、整体思路

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1555806.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

案例-博客页面简单实现

文章目录 本文内容只涉及前端1. 内容要求2. 画面展示初始化面演示视频 3. 注意事项4. 代码区js文件夹下的jquery.min.js内容登录代码列表页面创作页面 本文内容只涉及前端 1. 内容要求 登录页面实现博客列表页面实现博客创作页面实现 链接: 开源在线 Markdown 编辑器文本框可…

【黑马点评】 使用RabbitMQ实现消息队列——2.使用RabbitMQ监听秒杀下单

2 使用RabbitMQ实现消息队列 2.1 修改\hm-dianping\pom.xmlpom.xml文件 添加RabbitMQ的环境 <!-- RabbitMQ--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId> </depe…

国外电商系统开发-运维系统资产属性-命令执行功能

当前开发中&#xff0c;还不支持点击拓扑图标打开资产的功能&#xff0c;后期有时间补全对应的开发。 该功能如同Xshell、SecureCRT、Putty一样&#xff0c;可以批量的发送系统命令&#xff0c;让Linux服务器执行。 默认情况下&#xff0c;系统已经选择全部主机&#xff0c;如果…

约数个数约数之和

好久没发文章了.......不过粉丝还是一个没少...... 今天来看两道超级恶心的数论题目&#xff01; No.1 约数个数 No.2 约数之和 先来看第一道&#xff1a;约数个数 题目描述 给定 n 个正整数 ai​,请你输出这些数的乘积的约数个数,答案对 10^97 取模 输入格式 第一行包含…

CUDA、Pytorch、Pycharm的安装与配置

文章目录 一、CUDA安装1.检查英伟达驱动支持的最高CUDA版本 二、Pytorch的安装与环境配置1.选择是下载CPU版本还是GPU版本2.上Pytorch官网找到安装命令3.运行指令(1)CPU版本(2)GPU版本 4.验证5.安装其他所需模块(1)安装Matplotlib(2)安装 pillow&#xff08;可能anaconda已经给…

3D网格顶点颜色转纹理

顶点颜色是一种将颜色信息直接添加到网格顶点的简单方法。这通常是生成式 3D 模型&#xff08;如 InstantMesh&#xff09;生成网格的方式。但是&#xff0c;大多数应用程序更喜欢 UV 映射的纹理网格。 本教程介绍了一种将顶点颜色网格转换为 UV 映射的纹理网格的快速解决方案…

【Java数据结构】栈 (Stack)

【本节目标】 1. 栈的概念及使用 2. 相关 OJ 题 一、概念 栈&#xff1a;一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶&#xff0c;另一端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last…

Vue项目中通过插件pxtorem实现大屏响应式

一、原理 rem单位代表的是根节点的font-size大小&#xff0c;所以当我们在页面上使用rem去替代px的时候&#xff0c;就可以通过修改根节点font-size的值&#xff0c;动态地让页面上的元素根据不同浏览器宽高下去实现变化。 二、工具 1.postcss-pxtorem 作用&#xff1a;在编…

OpenAI Sora如何使用?

引言&#xff1a;OpenA推出首款AI视频模型Sora&#xff0c;震惊世界&#xff01; Sora是什么&#xff1f; Sora是OpenAI最新发布的文本生成视频&#xff08;Text to Video&#xff09;大模型&#xff0c;能生成长达60秒的视频 Sora能够创造出包括多个角色、特定动作类型以及…

10个令人惊叹的AI工具

AI 确实改变了游戏规则&#xff1b;它彻底改变了我们工作、创造和与技术互动的方式。虽然 ChatGPT、DALLE 和 Midjourney 等巨头占据了大部分头条新闻&#xff0c;但还有很多其他不为人知的 AI 工具和技术&#xff0c;大多数都同样令人惊叹。 以下是十种你可能没有听说过但绝对…

6个最受欢迎的大模型本地运行工具

运行大型语言模型 (LLM)&#xff08;如 ChatGPT 和 Claude&#xff09;通常涉及将数据发送到 OpenAI 和其他 AI 模型提供商管理的服务器。虽然这些服务是安全的&#xff0c;但一些企业更愿意将数据完全离线&#xff0c;以保护更大的隐私。 本文介绍了开发人员可以用来在本地运…

codetop标签动态规划大全C++讲解(二)!!动态规划刷穿地心!!学吐了家人们o(╥﹏╥)o

一篇只有十题左右&#xff0c;写少一点好复习 1.目标和2.分割等和子集3.完全平方数4.比特位计数5.石子游戏6.预测赢家7.不同的二叉搜索树8.解码方法9.鸡蛋掉落10.正则表达式匹配11.通配符匹配12.交错字符串 1.目标和 给你一个非负整数数组 nums 和一个整数 target 。 向数组中…

WindowsTerminal 美化-壁纸随机更换

目录 一. 相关网址二. 壁纸随机更换思路三. 指定 WindowsTermina 壁纸路径四. 编写脚本&#xff0c;随机替换壁纸4.1 powershell脚本4.2 .bat批处理脚本 四. 配置定时任务&#xff0c;添加触发器五. 效果 一. 相关网址 官方下载 Windows Terminal 官方Github微软商店 美化 Oh …

力扣之1285.找到连续区间的开始和结束

题目 sql建表语句&#xff1a; Create table If Not Exists Logs (log_id int); Truncate table Logs; insert into Logs (log_id) values (1); insert into Logs (log_id) values (2); insert into Logs (log_id) values (3); insert into Logs (log_id) values (7); inse…

白板2-数学基础

高斯分布1-极大似然估计 高斯分布2-极大似然估计-无偏&有偏 高斯分布3-从概率密度角度高斯分布4-局限性高斯分布5-边缘概率及条件概率高斯分布6-求联合概率分布

基于SpringBoot vue 医院病房信息管理系统设计与实现

博主介绍&#xff1a;专注于Java&#xff08;springboot ssm 等开发框架&#xff09; vue .net php python(flask Django) 小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设&#xff0c;从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆☆不然下次找…

DELL SC compellent存储的四种访问方式

DELL SC存储&#xff08;国内翻译为 康贝存储&#xff0c;英文是compellent&#xff09;, compellent存储是dell在大概10多年前收购的一家存储&#xff0c;原来这个公司就叫做compellent。 本文的阅读对象是第一次接触SC存储的技术朋友们&#xff0c;如何访问和管理SC存储。总…

一条广告变现3W+,半个月涨粉30W!简直太香了!

今天给大家分享个变现很猛的赛道&#xff0c; 这个赛道&#xff0c;我一开始关注到的时候&#xff0c;是一两个月前吧&#xff0c; 当时看到的时候&#xff0c;相关的笔记流量很猛&#xff0c; 而且相关的账号&#xff0c;起的号也很多&#xff0c; 我当时是看到那么多人都…

《数据结构》--栈【概念应用、图文并茂】

本节讲完栈下次再讲一下队列&#xff0c;最后补充一个串&#xff0c;我们的线性结构基本就完事了。下图中黄色框框圈中的是我们今日份内容(分为两篇博客)&#xff1a; 知识体系图 栈(Stack-LIFO)结构 栈的基础概念 栈(Stack)是一个后进先出(Last-In-First-Out)的一个特殊数据…

五种IO模型与阻塞IO

一、前言 在网络中通信的本质其实是网络中的两台主机的进程间进行通信&#xff0c;而进程通信的本质就是IO。 IO分为输入&#xff08;input&#xff09;和输出&#xff08;output&#xff09;站在进程的角度讲&#xff0c;进程出去数据为输出&#xff0c;外部数据进入进程为输…