• (muduo) 基础demo


    介绍

    原项目:

    GitHub - chenshuo/muduo

    环境安装方式:

    C++ muduo网络库知识分享01 - Linux平台下muduo网络库源码编译安装

    陈硕B站:

    bnu_chenshuo的个人空间-bnu_chenshuo个人主页-哔哩哔哩视频 (bilibili.com)

    Chen Shuo’s Homepage

    muduo 是一个在linux下的网络库。不跨平台。

    该库还是比较知名的,但是由于历史遗留问题,要依赖boost库等问题。

    有过一定的诟病,但是最为学习来说还是不错的,muduo库在实际项目中使用的人多吗? - 知乎 (zhihu.com)

    Code

    服务端code

    /**
     * muduo网络库给用户提供了两个主要的类
     * TcpServer
     * TcpClient
     *
     * epoll + 线程池
     * 好处:能够把网络I/O的代码和业务逻辑代码分开
     *  用户的连接与断开
     *  用户的读写事件
     */
    #include 
    #include 
    
    #include 
    #include 
    #include 
    
    using namespace muduo;
    using namespace muduo::net;
    
    /**
     * 基于muduo网络库开发服务端程序
     * 1. 组合TcpServer对象
     * 2. 创建EventLoop事件循环对象的指针
     * 3. 明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数
     * 4.
     * 在当前服务器类的构造函数当中,注册处理连接的回调函数和处理读写事件的回调函数
     * 5. 设置合适的服务端线程数量,muduo会自动分配IO线程和worker线程
     */
    class ChatServer {
    public:
        /**
         * @brief Construct a new Chat Server object
         *
         * @param loop 事件循环
         * @param listenAddr 监听端口
         * @param nameArg 命名
         */
        ChatServer(EventLoop* loop, const InetAddress& listenAddr,
                   const string& nameArg)
            : _server(loop, listenAddr, nameArg), _loop(loop) {
            // 给服务器注册用户连接的创建和断开回调
            _server.setConnectionCallback(
                std::bind(&ChatServer::onConnection, this, _1));
    
            // 给服务器注册用户读写回调
            _server.setMessageCallback(
                std::bind(&ChatServer::onMessage, this, _1, _2, _3));
    
            // 设置服务器的线程数量 1个IO线程 3个worker线程
            _server.setThreadNum(4);
        }
    
        void start() {
            std::cout << "Muduo Server Start" << std::endl;
            _server.start();
        }
    
    private:
        /**
         * 专门处理用户的连接创建和断开
         * epoll listenfd accept
         */
        void onConnection(const TcpConnectionPtr& conn) {
            // 连接成功
            if (conn->connected()) {
                std::cout << conn->peerAddress().toIpPort() << " -> "
                          << conn->localAddress().toIpPort() << " state:online "
                          << std::endl;
            }
            // 连接失败
            else {
                std::cout << conn->peerAddress().toIpPort() << " -> "
                          << conn->localAddress().toIpPort() << " state:offline "
                          << std::endl;
    
                // close(fd)
                conn->shutdown();
                // _loop->quit();
            }
        }
    
        /**
         * @param coon 连接
         * @param buf 缓冲区
         * @param time 接受到数据的时间信息
         */
        void onMessage(const TcpConnectionPtr& conn, Buffer* buffer,
                       Timestamp time) {
            std::string buf = buffer->retrieveAllAsString();
            std::cout << "recv data: " << buf << "time: " << time.toString()
                      << std::endl;
            // 回声服务器
            conn->send(buf);
        }
    
    private:
        TcpServer _server;
        EventLoop* _loop;  // epoll
    };
    
    int main() {
        EventLoop loop;
        InetAddress addr("127.0.0.1", 6000);
        ChatServer server(&loop, addr, "CharServer");
    
        // 启动服务
        server.start();
        // 以阻塞方式,等待事件
        loop.loop();
    
        return 0;
    }
    
    • 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
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113

    Makefile

    SRC += server.cpp
    TAR = server.out
    
    ${TAR} : ${SRC}
    	g++			 	\
    	$^ 				\
    	-o 				\
    	$@ 				\
    	-lmuduo_net 	\
    	-lmuduo_base 	\
    	-lpthread
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    简单讲解

    muduo网络库给用户提供了两个主要的类

    • TcpServer

    • TcpClient

    epoll + 线程池

    好处:能够把网络I/O的代码和业务逻辑代码分开

    • 用户的连接与断开

    • 用户的读写事件


    muduo使用起来还是简单和模板的。

    因为封装的比较好,直接设置回调即可。

    该代码主要内容TcpServerEventLoop

    分别管理服务和事件循环,并相关依赖。

    End

    一份简单的客户端代码见本文:

    (libevent) 基础demo


    当然可以直接用linux下的 telnet

  • 相关阅读:
    【基本算法题-2022.7.26】3.最短Hamilton路径
    xftp打开时提示需要更新或使用新版本
    LeetCode[剑指Offer54]二叉搜索树的第K大节点
    笔试强训48天——day24
    期望和方差
    【EI会议征稿】第八届先进能源科学与自动化国际研讨会(AESA 2024)
    (十一) 共享模型之无锁【CAS 与 volatile】
    【linux命令讲解大全】108.磁盘配额管理及使用者限制的实施方法
    Linux远程控制
    【小黑嵌入式系统第三课】嵌入式系统硬件平台(一)——概述、总线、存储设备(RAM&ROM&FLASH)
  • 原文地址:https://blog.csdn.net/CUBE_lotus/article/details/133365732