基于muduo网络库开发服务器程序和CMake构建项目 笔记

news2025/2/5 0:32:01

跟着施磊老师做C++项目,施磊老师_腾讯课堂 (qq.com)

一、基于muduo网络库开发服务器程序

  1. 组合TcpServer对象
  2. 创建EventLoop事件循环对象的指针
  3. 明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数
  4. 在当前服务器类的构造函数当中,注册处理连接的回调函数和处理读写事件的回调函数
  5. 设置合适的服务端线程数量,muduo库会自己分配I/O线程和worker线程
  • test.cpp 
/*
    muduo网络库给用户提供了两个主要的类
    TcpServer: 用于编写服务器程序的
    TcpClient: 用于编写客户端程序的

    epoll + 线程池
    好处:能够把网络I/O的代码和业务代码区分开
    对于业务代码主要暴露两个:用户的连接和断开;用户的可读写事件

    告诉muduo库,你对哪些事件感兴趣,并且你给我提前注册一个回调函数,
    当这些事情发生时,我会通知你,你去做你的事情吧!
*/
#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
#include <iostream>
#include <functional>
#include <string>

using namespace std;
using namespace muduo;
using namespace muduo::net;
using namespace placeholders;
// 基于muduo网络库开发服务器程序
/*
    1.组合TcpServer对象
    2.创建EventLoop事件循环对象的指针
    3.明确TcpServer构造函数需要什么参数,输出ChatServer的构造函数
    4.在当前服务器类的构造函数当中,注册处理连接的回调函数和处理读写事件的回调函数
    5.设置合适的服务端线程数量,muduo库会自己分配I/O线程和worker线程
*/
class ChatServer {
public:
    // 初始化TcpServer   loop:事件循环   listenAddr:IP+Port   nameArg:服务器的名字
    ChatServer(EventLoop *loop, const InetAddress &listenAddr, const string &nameArg)
        : m_server(loop, listenAddr, nameArg), m_loop(loop) {
        // 给服务器注册用户连接的创建和断开回调
        m_server.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1));
        // 给服务器注册用户读写事件回调
        m_server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));
        // 设置服务器端的线程数量 1个I/O线程 3个worker线程
        m_server.setThreadNum(4);
    }
    // 开启事件循环
    void start() {
        m_server.start();
    }
private:
    // 专门处理用户的连接创建和断开  epoll listenfd accept
    void onConnection(const TcpConnectionPtr &conn) {
        cout<<conn->peerAddress().toIpPort() <<" -> "
             <<conn->localAddress().toIpPort() <<" is ";
        if(conn->connected()) {
            cout<<"state:online"<<endl;
        }
        else {
            cout<<"state:offline"<<endl;
            conn->shutdown(); // close(fd)
            // m_loop->quit();
        }
    }
    // 专门处理用户的读写事件  conn连接/buf缓冲区/time接收到数据的时间信息
    void onMessage(const TcpConnectionPtr &conn, Buffer *buffer, Timestamp time) {
        string buf = buffer->retrieveAllAsString();
        cout<<"recv data:"<<buf<<" time:"<<time.toString()<<endl;
        conn->send(buf);
    }
    TcpServer m_server; // #1
    EventLoop *m_loop;  // #2 epoll
};

int main() {
    EventLoop loop; // epoll
    InetAddress addr("127.0.0.1",6000);
    ChatServer server(&loop, addr, "ChatServer");
    server.start(); // listenfd epoll_ctl => epoll
    loop.loop(); // epoll_wait以阻塞方式等待新用户连接,已连接用户的读写事件等
    return 0;
}
  • 生成server文件,注意muduo_net要在muduo_base前面,命令如下:
g++ test.cpp -o server -lmuduo_net -lmuduo_base -lpthread

二 注意:本文使用到了有关muduo的TcpServer.h中找到setConnectionCallback和setMessageCallback,点击跳转到有关connectionCallback的头文件中去

  /// Set connection callback.
  /// Not thread safe.
  void setConnectionCallback(const ConnectionCallback& cb)
  { connectionCallback_ = cb; }

  /// Set message callback.
  /// Not thread safe.
  void setMessageCallback(const MessageCallback& cb)
  { messageCallback_ = cb; }

有关muduo的Callbacks.h

typedef std::function<void (const TcpConnectionPtr&)> ConnectionCallback;

// the data has been read to (buf, len)
typedef std::function<void (const TcpConnectionPtr&,
                            Buffer*,
                            Timestamp)> MessageCallback;

找到对应的Callback,我们就可以知道回调函数的参数和返回类型了

    // 专门处理用户的连接创建和断开  epoll listenfd accept
    void onConnection(const TcpConnectionPtr &conn) {
        ...
    }
    // 专门处理用户的读写事件  conn连接/buf缓冲区/time接收到数据的时间信息
    void onMessage(const TcpConnectionPtr &conn, Buffer *buffer, Timestamp time) {
        ...
    }

我的往期文章: 

在windows和Linux中的安装 boost 以及 安装 muduo-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_41987016/article/details/135963909?spm=1001.2014.3001.5501

三、vscode实现一键运行server

tasks.json

{
	"version": "2.0.0",
	"tasks": [
		{
			"type": "cppbuild",
			"label": "C/C++: g++ 生成活动文件",
			"command": "/usr/bin/g++",
			"args": [
				"-fdiagnostics-color=always",
				"-g",
				"-o",
				"${workspaceFolder}/bin/app",
				// "${fileDirName}/${fileBasenameNoExtension}",
				// "-lmuduo_net",
				// "-lmuduo_base",
				// "-lpthread"
			],
			"options": {
				"cwd": "${workspaceFolder}"
			},
			"problemMatcher": [
				"$gcc"
			],
			"group": {
				"kind": "build",
				"isDefault": true
			},
			"detail": "编译器: /usr/bin/g++"
		}
	]
}
  • launch.json
{
    // 使用 IntelliSense 了解相关属性。 
    // 悬停以查看现有属性的描述。
    // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) 启动",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/bin/app",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "为 gdb 启用整齐打印",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "将反汇编风格设置为 Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        }

    ]
}
  • CMakeLists.txt
cmake_minimum_required(VERSION 3.28.0)
project(test)
add_executable(server test.cpp)

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
target_link_libraries(server -lmuduo_net -lmuduo_base -lpthread) 

cmake -B build
cmake --build build

二、CMake构建项目

testmuduo存放CMakeLists.txt和test.cpp

  • CMakeLists.txt
cmake_minimum_required(VERSION 3.28.0)
project(test)

# 配置头文件搜索路径
# include_directories()
# 配置库文件搜索路径
# link_directories()
# 设置需要编译的源文件列表
set(SRC_LIST test.cpp)
# 把.指定路径下的所有源文件名字放入变量名SRC_LIST里面
# aux_source_directory(. SRC_LIST)

# 生成可执行文件server,由SRC_LIST变量所定义的源文件编译生成
add_executable(server ${SRC_LIST})

message("打印一下bin目录:" ${BIN})
# 设置可执行文件的存放路径
set(EXECUTABLE_OUTPUT_PATH ${BIN})

# 表示server这个目标程序,需要链接这三个muduo_net muduo_base pthread库文件
# target_link_libraries(server -lmuduo_net -lmuduo_base -lpthread) 
target_link_libraries(server muduo_net muduo_base pthread) 


与testmuduo文件夹同目录的CMakeLists.txt

  • CMakeLists.txt
cmake_minimum_required(VERSION 3.28.0)
project(test_project)

set(BIN ${PROJECT_SOURCE_DIR}/bin)

# # 配置编译选项
# set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)

# 指定搜索的子目录
add_subdirectory(testmuduo)

在此终端执行命令:

cmake -B build 
cmake --build build

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

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

相关文章

tcp/ip模型中,帧是第几层的数据单元?

在网络通信的世界中&#xff0c;TCP/IP模型以其高效和可靠性而著称。这个模型是现代互联网通信的基石&#xff0c;它定义了数据在网络中如何被传输和接收。其中&#xff0c;一个核心的概念是数据单元的层级&#xff0c;特别是“帧”在这个模型中的位置。今天&#xff0c;我们就…

C++ STL库详解:容器适配器stack和queue的结构及功能

一、stack 1.1stack的介绍 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack是作为容器适配器被实现的&#xff0c;容器适配器即是对特定类封装作为其底层的容器&#xf…

【目标跟踪】3D点云跟踪

文章目录 一、前言二、代码目录三、代码解读3.1、文件描述3.2、代码框架 四、关联矩阵计算4.1、ComputeLocationDistance4.2、ComputeDirectionDistance4.3、ComputeBboxSizeDistance4.4、ComputePointNumDistance4.5、ComputePointNumDistance4.6、result_distance 五、结果 一…

实现div拖拽demo

示例代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title>&…

51单片机编程应用(C语言):数码管

目录 1.数码管原理 一位数码管引脚定义&#xff1a; 四位一体数码管&#xff1a; 多个数码管同时显示不同数字 51单片机的数码管的原理图 51单片机实现静态显示和动态显示 静态显示&#xff1a; 动态显示&#xff1a; 1.数码管原理 一位数码管引脚定义&#xff1a; 数码…

idea查看日志的辅助插件 --- Grep Console (高亮、取消高亮)

&#x1f680; 分享一款很有用的插件&#xff1a;Grep Console &#x1f680; 我们在查看日志的时候可能会有遗漏&#xff0c;使用这款插件可以让特定的关键词高亮&#xff0c;可以达到不遗漏的效果&#xff01; 如果你是一个开发者或者对日志文件分析感兴趣&#xff0c;不要…

linux搭建jupyter

查看虚拟环境 conda info --envs进入虚拟环境 conda activate my_env pip install jupyter pip install ipykernel1. jupyter notebook启动 1.1 创建临时jupyter notebook任务 jupyter notebook --ip0.0.0.0 --no-browser --allow-root --notebook-dir/home/xxx1.2 jupyter…

Xcode报fatal error: ‘XXX.h‘ file not found

在Xcode中遇到 "fatal error: XXX.h file not found" 的错误通常是由于缺少头文件或头文件路径配置不正确导致的。 以下仅为我的解决方案&#xff1a; 1.点击项目名——>显示此页面 2.选择Build Settings——>输入 Search Paths 3. 点击空白处添加路径 4…

使用浏览器开发工具分析性能

使用浏览器开发工具分析性能 一、网络分析二、性能分析 一、网络分析 1、面板概览&#xff1a; Controls (控件) : 控制面板的功能Filters (过滤器) : 控制在请求列表中显示哪些资源Overview (概览) : 展示检索资源的时间轴&#xff0c;多个垂直堆叠的栏意味着这些资源被同时…

2024杭州国际安防展览会:引领数字城市安全与智能未来

随着科技的不断进步&#xff0c;数字城市已经成为未来城市发展的重要趋势。作为数字城市建设的重要组成部分&#xff0c;安防技术的创新与应用对于保障城市安全、提高生活品质具有重要意义。为此&#xff0c;2024杭州国际安防展览会将于4月份在杭州国际博览中心隆重召开&#x…

储能新纪元:第十三届中国国际储能大会(CIES2023)深度洞察与未来趋势

随着全球能源结构的持续优化和可再生能源的迅猛发展&#xff0c;储能技术作为支撑能源转型的关键力量&#xff0c;日益受到世界各国的关注。 在这一背景下&#xff0c;2023年第十三届中国国际储能大会&#xff08;CIES2023&#xff09;的召开&#xff0c;无疑为行业内外人士提…

PDF中公式转word

效果&#xff1a;实现pdf中公式免编辑 step1: 截图CtrlAltA&#xff0c;复制 step2: SimpleTex - Snip & Get 网页或客户端均可&#xff0c;无次数限制&#xff0c;效果还不错。还支持手写、文字识别 单张图片&#xff1a;选 手写板 step3: 导出结果选择 注&#xff1a;…

网络协议与攻击模拟_12DNS协议及Windows部署DNS服务器

1、了解域名的结构 2、DNS查询过程 3、Windwos server部署DNS服务器 4、分析流量 实施DNS欺骗 再分析 一、DNS域名系统 1、DNS简介 DNS&#xff08;Domain Name system&#xff09;域名系统&#xff0c;作为将域名的IP地址的相互映射关系存放在一个分布式的数据库&#xff0c…

OBB头篇 | 原创自研 | YOLOv8 更换 SEResNeXtBottleneck 头 | 附详细结构图

左图:ResNet 的一个模块。右图:复杂度大致相同的 ResNeXt 模块,基数(cardinality)为32。图中的一层表示为(输入通道数,滤波器大小,输出通道数)。 1. 思路 ResNeXt是微软研究院在2017年发表的成果。它的设计灵感来自于经典的ResNet模型,但ResNeXt有个特别之处:它采用…

小米服务治理——客户端熔断器(Google SRE客户端熔断器)

目录 前言 一、什么是Google SRE熔断器 二、Google SRE 熔断器的工作流程&#xff1a; 三、客户端熔断器 (google SRE 熔断器) golang GRPC 实现 四、客户端熔断器 (google SRE 熔断器) golang GRPC单元测试 大家可以关注个人博客&#xff1a;xingxing – Web Developer …

【动态规划】【C++算法】1340. 跳跃游戏 V

作者推荐 【动态规划】【字符串】【表达式】2019. 解出数学表达式的学生分数 本文涉及知识点 动态规划汇总 LeetCode1340跳跃游戏 V 给你一个整数数组 arr 和一个整数 d 。每一步你可以从下标 i 跳到&#xff1a; i x &#xff0c;其中 i x < arr.length 且 0 < x…

提及闭包函数,不得不说【python装饰器】

什么是装饰器 1. python装饰器是用于拓展原来函数功能的一种函数&#xff0c;目的是在不改变原函数的情况下&#xff0c;给函数增加功能。 2. 装饰器是通过闭包实现&#xff0c;所以讲装饰器首先得知道什么是闭包。 前言 什么是闭包 一、什么是闭包 1. 一个定义在函数内部的函…

[职场] 个人简历教育背景怎么填 #其他#笔记#媒体

个人简历教育背景怎么填 一个人的受教育程度很大部分决定了此人的专业素质&#xff0c;简历中的教育背景是HR衡量求职者的标准&#xff0c;因此教育背景部分在简历中比较靠前。 怎么写教育背景&#xff1f; 1、时间 首先&#xff0c;最重要的是你要注明好时间&#xff0c;时间都…

idea搭建spring5.3.x源码环境

1.写在前面的话 碰到了不少想阅读或者学习spring源码的同学&#xff0c;但是第一步搭建这个源码阅读环境就能难倒了一大批人。下面我就以spring5.3.x这个源码分支&#xff0c;来具体演示一下搭建过程。 2. 下载源码 下载源码这一步&#xff0c;说实话&#xff0c;由于某些原…

STM32控制DS18B20温度传感器获取温度

时间记录&#xff1a;2024/1/28 一、DS18B20温度传感器介绍 &#xff08;1&#xff09;测温范围-55℃~125℃&#xff0c;在-10℃到85℃范围内误差为0.4 &#xff08;2&#xff09;返回的温度数据为16位二进制数据 &#xff08;3&#xff09;STM32和DS18B20通信使用单总线协议…