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

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

跟着施磊老师做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.kler.cn/a/226887.html

相关文章:

  • Kubernetes集群搭建
  • 【开源】基于JAVA+Vue+SpringBoot的教学资源共享平台
  • Django模型(八)
  • 华为机考入门python3--(5)牛客5-进制转换
  • Web安全
  • Java SWT Composite 绘画
  • 数据结构.二叉树
  • vue3 之 组合式API - setup选项
  • C#中检查空值的最佳实践
  • 【game——关机程序】
  • 通过servlet设计一个博客系统
  • ServletConfig类和ServletContext类
  • 简单几步,借助Aapose.Cells将 Excel 工作表拆分为文件
  • binder android
  • Android Studio开发配置(gradle配置)
  • HttpRunner自动化测试之实现参数化传递
  • R语言分析任务:
  • MacOS安装dmg提示已文件已损坏的解决方法
  • 计算机硬件基础知识
  • 记一次 Android CPU高使用率排查