1.10.C++项目:仿muduo库实现并发服务器之Acceptor模块的设计

一、Acceptor模块:这是一个对于通信连接进行整体管理的一个模块,对一个连接的操作都是通过这个模块来进行!

二、提供的功能

Acceptor模块是对Socket模块,Channel模块的⼀个整体封装,实现了对⼀个监听套接字的整体的管

理。

三、实现思想

(一)功能

  1. 实现向Channel提供可读事件的IO事件处理回调函数,函数的功能其实也就是获取新连接。
  2. 为新连接构建⼀个Connection对象出来。

(二)意义

当获取了一个新建连接的描述符后,需要为这个通信连接,封装一个connection对象,设置不同回调。

注意:因为Acceptor模块本身并不知道一个链接产生了某个事件该如何处理,因此获取一个通信连接后,Connection的封装,以及事件回调的设置都应该由服务器模块来进行!

(三)功能设计

回调函数设置------新建连接获取成功的回调设置,由服务器来指定!

四、框架

cpp 复制代码
/*
Acceptor 模块,对监听套接字进行管理!
        1. 创建一个监听套接字
        2. 启动读事件监控
        3. 事件触发后,获取新连接
        4. 调用新连接获取成功后的回调函数!
                4. 为新连接创建Connection进行管理(这一步不是Acceptor模块操作,应该是服务器模块)
        因为Acceptor模块只进行监听连接的管理,因此获取到新连接的描述符后,对于新连接描述符如何处理并不关心!
        对于新连接如何处理,应该是服务器模块关心管理!
        服务器模块,实现了一个对于新连接描述符处理的函数,将这个函数设置给Acceptor模块的回调函数!
*/

五、代码

cpp 复制代码
class Acceptor {
        private:
                Socket _socket; // 用于创建监听套接字
                EventLoop *_loop;  // ⽤于对监听套接字进⾏事件监控
                Channel _channel;  // ⽤于对监听套接字进⾏事件管理
                using AcceptCallback = std::function<void(int)>;
                AcceptCallback _accept_callback;
        private:
        /*监听套接字的读事件回调处理函数---获取新连接,调⽤_accept_callback函数进⾏新连接处理*/ 
                void HandleRead() {
                        int newfd = _socket.Accept();
                        if (newfd < 0) {
                                return ;
                        }
                        if (_accept_callback) _accept_callback(newfd);
                }
                int CreateServer(int port) {
                        bool ret = _socket.createServer(port);
                        assert(ret == true);
                        return _socket.Fd();
                }
        public:
        /*不能将启动读事件监控,放到构造函数中,必须在设置回调函数后,再去启动*/
        /*否则有可能造成启动监控后,⽴即有事件,处理的时候,回调函数还没设置:新连接得不到处理,且资源泄漏*/
                Acceptor(EventLoop* loop,int port) : _socket(createServer(port)),_loop(loop),_channel(loop,_socket.Fd()) {
                        _channel(loop, _socket.Fd()) {
                        _channel.SetReadCallback(std::bind(&Acceptor::HandleRead, this));
                }
                void SetAcceptCallback(const AcceptCallback &cb) { 
                        _accept_callback = cb; 
                }
                void Listen() {
                        _channel.EnableRead(); 
                }
};
相关推荐
oh,huoyuyan23 分钟前
JS 动态网页抓不到?试试火车采集器网页抓取工具
开发语言·javascript·ecmascript
晓晓_za89866837 分钟前
Geo 优化服务 CI/CD 流水线搭建:源码自动构建、测试与灰度发布
运维·服务器·tcp/ip·spring·缓存·ci/cd
风流 少年41 分钟前
hutool
java·服务器·开发语言
H_oRIZoN_1 小时前
Linux入门DAY27(文件IO(系统调用)详解|open/read/write/lseek)
java·linux·服务器
一木 之林1 小时前
四、STL容器与数据结构
开发语言·数据结构·c++
QX_hao1 小时前
【Go】--Cobra-cli的用法
开发语言·后端·golang
程与留1 小时前
07_QMainWindow 与应用程序框架——菜单栏、工具栏、状态栏
c++·qt
艾醒(AiXing-w)1 小时前
LangChain 1.0 入门(三):稳定性双核心——重试机制+速率限速器参数详解与实战
开发语言·langchain·php
一个处女座的程序猿2 小时前
Computer之Server:caddy(可扩展的服务器平台)的简介、安装和使用方法、案例应用之详细攻略
运维·服务器·server·caddy
总有刁民想爱朕ha2 小时前
Python PyQt5图片批量转MP4视频工具:本地离线免费无水印,完整代码
开发语言·python·qt