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


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

    在这里插入图片描述

    二、提供的功能

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

    三、实现思想

    (一)功能

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

    (二)意义

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

    (三)功能设计

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

    四、框架

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

    五、代码

    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(); 
                    }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    Matlab---figure图窗属性与设置与交互设置
    使用platformio+arduino开发自定义板子STM32G070
    树状数组——数组两种初始化方式+单点增加+查询前缀和+插入
    【RuoYi-Vue-Plus】学习笔记 37 - OSS模块(七)V4.2.0+ 版本OSS加载流程
    java+springboot+vue水果蔬菜篮子商城经营平台系统
    【网络通信 -- WebRTC】项目实战记录 -- mediasoup android 适配 webrtc m94
    1550_AURIX_TC275_锁相环的操作
    长三角实现区块链电子医疗票据互联互通,蚂蚁链提供技术支持
    Scala入门
    用于机器学习的 NumPy(ML)
  • 原文地址:https://blog.csdn.net/weixin_54447296/article/details/133682170