当前位置: 首页 > ai >正文

施磊老师基于muduo网络库的集群聊天服务器(二)

文章目录

  • Cmake简单介绍
    • Cmake与Makefile
    • Cmake配置
    • CmakeLists.txt 编写
    • 完整cmake例子
    • 文件夹杂乱问题
    • 多级目录Cmake
    • vscode 极其推荐 的 cmake方式
  • Mysql环境与编程
    • mysql简单使用
    • User表
    • Friend表
    • AllGroup表
    • GroupUser表
    • OfflineMessage表
  • 集群聊天项目工程目录创建
  • 网络模块代码Chatserver
    • 头文件
    • 类函数定义文件
    • 主函数文件

Cmake简单介绍

Cmake与Makefile

Makefile 在大项目里, 很难写 出来, 推荐Cmake

  1. Makefile
    • 直接构建工具:定义编译规则(如 gcc -o main main.c),由 make 直接执行。
    • 手动编写:需指定每个文件的依赖和命令,适合小型项目。
    • 平台差异:不同系统的 make 可能有兼容性问题。
  2. CMake
    • 构建系统生成器:通过 CMakeLists.txt 描述项目结构,自动生成平台相关的构建文件(如 Makefile 或 IDE 工程)。
    • 跨平台:一套配置适配多平台(Linux/Mac/Windows)。
    • 高级功能:自动处理依赖、安装规则等,适合中大型项目。

Cmake配置

直接手写 cmake配置文件CMakeLists.txt, 命令行执行, 是可行的

vscode的cmake插件, 再写 cmake 时 会有代码提示----------> cmake 与 cmake tools

  1. cmake tools 设置里, 在对应的 本机或者 远程 设置一下 cmake 的 build enviroment: 添加一下 cmake的 路径(需要安装 cmake)

    在这里插入图片描述

CmakeLists.txt 编写

  1. CMAKE_CXX_FLAGS 是 CMake 中用于设置 全局 C++ 编译器选项 的变量,影响项目中所有 C++ 目标的编译行为。

  2. 在 CMake 中,set() 命令用于 定义或修改变量,是 CMake 脚本中最基础且重要的命令之一

    set(变量名 值)  # 定义普通变量
    
  3. 在 CMake 中,add_executable 是一个核心命令,用于定义可执行文件目标

    add_executable(<目标名称> [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] <源文件列表>)
    

    最主要的是 目标名称 和 源文件列表

    例子:

    #单文件
    add_executable(hello_world main.cpp)#多文件
    add_executable(my_app main.cpp utils.cpp include/utils.h
    )#条件编译--不同平台
    if(WIN32)add_executable(my_win_app WIN32 win_main.cpp)
    else()add_executable(my_win_app main_unix.cpp)
    endif()#使用变量组织源文件
    set(APP_SOURCES src/main.cpp src/core.cpp
    )
    add_executable(my_app ${APP_SOURCES})
    
  4. 在 CMake 中,target_link_libraries 是一个关键命令,用于为指定的目标(可执行文件或库)链接依赖库。它管理目标的所有链接依赖关系,是现代 CMake 推荐的做法。 — 更多使用, 多见多总结 — 老师pdf也有很多, 多看

    target_link_libraries(<目标名称><PRIVATE|PUBLIC|INTERFACE> <库1> [<库2>...][<PRIVATE|PUBLIC|INTERFACE> <库3>...]
    )
    
  5. aux_source_directory 是 CMake 中一个 用于自动收集源文件 的命令,但现代 CMake 已不再推荐使用它。

    aux_source_directory(<目录路径> <变量名>)
    

    为什么不推荐使用?

    1. 不会自动检测新增文件
      需要手动重新运行 CMake 才能识别新添加的源文件。
    2. 包含无关文件风险
      可能意外包含测试文件、备份文件(如 main.cpp.bak)。
    3. 破坏构建系统的确定性
      隐式文件收集会导致构建行为不可预测。
    4. 与现代 CMake 理念冲突
      现代 CMake 强调显式声明源文件(target_sources())。

    推荐使用 set 手动, 很麻烦

完整cmake例子

cmake_minimum_required(VERSION 3.0)
project(main) #工程名# 配置编译选项
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)# 配置头文件搜索路径
include_directories()
# 配置库文件搜索路径
link_directories()#设置需要编译的 源文件列表
set(SRC_LIST ./nuduo_server.cpp)#把 . 指定路径下的 所有源文件名字 放入变量名--不用手动一个个输入
# aux_source_directory(. SRC_LIST) #暂时不用#生成可执行文件
add_executable(server ${SRC_LIST})# 表示server 这个目标程序 需要链接的 库
target_link_libraries(server muduo_net muduo_base pthread)

然后 先执行 cmake .----> 得到 makefile文件 —> 再make 即可

文件夹杂乱问题

直接 使用上面的 构建, 生成许多杂乱的 文件夹

一般 开源性代码 会有以下结构:

目录/文件用途描述文件类型示例
bin/存放生成的可执行文件(二进制文件)myapp, myapp.exe
lib/存放编译生成的库文件libmylib.a, mylib.so
include/存放项目的公共头文件utils.h, config.hpp
src/存放项目的主要源代码文件main.cpp, module.c
build/存放CMake生成的构建文件Makefile, build.ninja
example/存放示例代码或测试用例demo.cpp, test_case.py
thirdparty/存放第三方依赖库或源码googletest/, boost/
CMakeLists.txtCMake的主配置文件-
autobuild.sh自动化构建脚本-
  1. 在 CMake 中,EXECUTABLE_OUTPUT_PATH 是一个用于设置可执行文件输出路径的全局变量。它控制通过 add_executable() 生成的可执行文件的存放位置。

    在 CMake 中,PROJECT_SOURCE_DIR 是一个预定义变量,表示当前项目的根目录路径(即包含顶层 CMakeLists.txt 的目录)。

    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)
    
  2. 建立 build 文件, 进入build 进行 cmake .., 之前的 杂乱的文件夹就在这个目录里了, 并且 可执行文件 在bin目录里

  3. 完整如下:

    cmake_minimum_required(VERSION 3.0)
    project(main) #工程名# 配置编译选项
    set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)# 配置头文件搜索路径
    include_directories()
    # 配置库文件搜索路径
    link_directories()#设置需要编译的 源文件列表
    set(SRC_LIST ./nuduo_server.cpp)# 设置可执行文件最终目录
    set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)# 设置库文件最终目录
    set(LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)#把 . 指定路径下的 所有源文件名字 放入变量名--不用手动一个个输入
    # aux_source_directory(. SRC_LIST) #暂时不用#生成可执行文件
    add_executable(server ${SRC_LIST})# 表示server 这个目标程序 需要链接的 库
    target_link_libraries(server muduo_net muduo_base pthread)

多级目录Cmake

内部的CMakeLists.txt 不需要 前5行, 这是 cmake的 入口
把这5行 放入 最外部的 CMakeLists.txt, 并且 加入 指定搜索的 子目录 即可

cmake_minimum_required(VERSION 3.0)
project(main) #工程名# 配置编译选项
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)# 指定搜索的 子目录
add_subdirectory(testmuduo)

vscode 极其推荐 的 cmake方式

vscode 插件 会有图标, 使用这个 进行 编译------> 即完成, 并会 外部 自动构建 build 文件

在这里插入图片描述

注意: 仅会自动构建 build 文件, bin 文件 还需要手动指定, 在 内部CMakeLists.txt 里 进行

VS Code CMake 插件的自动化机制

(1) 自动行为说明

  • 自动生成 build/ 目录
    插件默认会在项目根目录下创建 build/(或用户配置的路径),自动处理以下内容:

    mkdir -p build && cd build
    cmake .. -DCMAKE_BUILD_TYPE=Debug  # 自动选择编译器工具链
    
  • 实时更新
    插件会监控 CMakeLists.txt 和源码文件的修改,但不会实时构建,仅在以下情况触发:

    • 手动点击编译按钮
    • 保存文件时(若开启 "cmake.configureOnEdit": true
    • 执行调试/运行任务时

(2) 优势

  • 无需手动输入 CMake 命令
  • 自动匹配编译器工具链(通过 CMake: Scan for Kits
  • 与 VS Code 调试功能深度集成

Cmake 到此为止-----> 更多内容 见 pdf

Mysql环境与编程

登录 之前写过, 略

mysql 有课程, 建议看一下 — > 必须要了解 数据库 mysql !!!

mysql简单使用

  1. 创建数据库:

    CREATE DATABASE database_name;   // 大小写都行
    
  2. 选择要操作的 数据库:

    use database_name; 
    
  3. 查看默认的字符编码:

    show variables like "char%";
    

    修改表的字符编码:alter table user default character set utf8;
    修改属性的字符编码:alter table user modify column name varchar(50) character set utf8;

  4. 从已有的 sql文件读取, 需要先创建 一个数据库, 并且选中它进行操作, 再 source ./<..>.sql

  5. 根据表, 在mysql里 进行创建. — 具体表

    User表

    字段名称字段类型字段说明约束
    idINT用户idPRIMARY KEY, AUTO_INCREMENT
    nameVARCHAR(50)用户名NOT NULL, UNIQUE
    passwordVARCHAR(50)用户密码NOT NULL
    stateENUM(‘online’,‘offline’)当前登录状态DEFAULT ‘offline’

    Friend表

    字段名称字段类型字段说明约束
    useridINT用户idNOT NULL, 联合主键
    friendidINT好友idNOT NULL, 联合主键

    AllGroup表

    字段名称字段类型字段说明约束
    idINT组idPRIMARY KEY, AUTO_INCREMENT
    groupnameVARCHAR(50)组名称NOT NULL, UNIQUE
    groupdescVARCHAR(200)组功能描述DEFAULT ‘’

    GroupUser表

    字段名称字段类型字段说明约束
    groupidINT组idNOT NULL, 联合主键
    useridINT组员idNOT NULL, 联合主键
    grouproleENUM(‘creator’,‘normal’)组内角色DEFAULT ‘normal’

    OfflineMessage表

    字段名称字段类型字段说明约束
    useridINT用户idNOT NULL
    messageVARCHAR(500)离线消息(存储Json字符串)NOT NULL

集群聊天项目工程目录创建

略—> bin build include src thirdparty 文件夹

外层 CMakeLists.txt 和 src 的两层 CMakeLists.txt

cmake_minimum_required(VERSION 3.0)
project(main) #工程名# 配置编译选项
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -g)# 配置最终的可执行文件输出的路径
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)# 配置 头文件 搜索路径
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_SOURCE_DIR}/include/server)# 加载子目录  src   既然进去, 就有 CMakeLists.txt
add_subdirectory(src)
# 加载子目录  src   既然进去, 就有 CMakeLists.txt
add_subdirectory(server)
# 所有源文件
aux_source_directory(. SRC_LIST)
# 生成可执行
add_executable(Chatserver ${SRC_LIST})# 链接库
target_link_libraries(Chatserver muduo_net muduo_base pthread)

网络模块代码Chatserver

hpp文件 写声明

源文件 进行定义使用

头文件

include/chatserver.hpp

#ifndef CHATSERVER_H
#define CHATSERVER_H#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>
using namespace muduo;
using namespace muduo::net;// 聊天服务器主类
class ChatServer
{
public:// 初始化聊天服务器对象ChatServer(EventLoop *loop,const InetAddress &listenAddr,const string &nameArg);// 启动服务void start();private:// 上报连接 相关信息的回调void onConnect();// 上报读写事件相关信息的 回调void onMessage();TcpServer _server; // 组合的muduo库, 实现服务器功能的 类对象EventLoop *_loop;  // 指向事件循环对象的 指针
};#endif 

类函数定义文件

src/server/chatserver.cpp

不完整, 回调内部 还没写

#include "chatserver.hpp"#include <functional>
using namespace std;
using namespace placeholders;// 类外 定义成员函数
ChatServer::ChatServer(EventLoop *loop,const InetAddress &listenAddr,const string &nameArg): _server(loop, listenAddr, nameArg), _loop(loop)
{// 注册连接回调函数_server.setConnectionCallback(std::bind(&ChatServer::onConnect, this, _1));// 注册消息回调_server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));// 设置线程数_server.setThreadNum(4);
}void ChatServer::start()
{_server.start();
}void ChatServer::onConnect(const TcpConnectionPtr& conn)
{}void ChatServer::onMessage(const TcpConnectionPtr& conn,Buffer* buf,Timestamp time)
{   }

主函数文件

src/server/main.cpp

#include "chatserver.hpp"
#include <iostream>
using namespace std;int main()
{EventLoop loop;InetAddress addr("127.0.0.1", 6000);ChatServer server(&loop, addr, "ChatServer");server.start();loop.loop();return 0;
}

http://www.xdnf.cn/news/193.html

相关文章:

  • 十天借助 Trae 实现 “幸运塔塔屋” 小程序时光记忆功能之旅
  • Xcode16 调整 Provisioning Profiles 目录导致证书查不到
  • 多模态记忆融合:基于LSTM的连续场景生成——突破AI视频生成长度限制
  • Orgin为柱状图加趋势线
  • 零基础上手Python数据分析 (17):[案例实战] 电商销售数据分析 - 从数据到洞察的全流程演练
  • Docker容器虚拟化存储架构
  • 关于EXPLAIN ANALYZE 工具的解析及使用方法(AI)
  • 《深入探秘JavaScript原型链与继承机制:解锁前端编程的核心密码》
  • 【python报错解决训练】
  • 阿里云镜像加速仅支持阿里云产品了
  • ChatUI vs Ant Design X 技术选型对比
  • MODBUS TCP 转 CANOpen
  • Kaggle-Bag of Words Meets Bags of Popcorn-(二分类+NLP+Bert模型)
  • Mac 选择下载安装工具 x86 还是 arm64 ?
  • gl-matrix 库简介
  • 【java 13天进阶Day06】Map集合,HashMapTreeMap,斗地主、图书管理系统,排序算法
  • 实验2:turtle 库绘制进阶图形
  • Linux服务器配置Anaconda环境、Pytorch库(图文并茂的教程)
  • java基础从入门到上手(九):Java - List、Set、Map
  • 每天学一个 Linux 命令(20):find
  • 23种设计模式-创建型模式之抽象工厂模式(Java版本)
  • 【含文档+PPT+源码】基于Python的股票数据可视化及推荐系统的设计与实现
  • Oracle 11g通过dg4odbc配置dblink连接PostgreSQL
  • 从头学 | 目标函数、梯度下降相关知识笔记(一)
  • 边缘计算网关组态功能的定义
  • 阀门轴承电动车工件一键精修软件
  • vue2.6.12 安装babel 以使用 可选链 ?. 和空值合并 ??
  • 【Vue3代理机制详解:从原理到实践】
  • 医疗行业如何构建合成数据平台?——技术、合规与实践全景
  • Jenkins的使用及Pipeline语法讲解