muduo网络库介绍

muduo网络库是陈硕大神开发的基于主从Reactor模式的,事件驱动的高性能网络库。

网络编程中有很多是事务性的工作,使用muduo网络库,用户只需要填上关键的业务逻辑代码,并将回调注册到框架中,就可以实现完整的网络服务。

muduo网络库的核心是one loop per thread + thread pool,有一个main Reactor负责accept连接,然后将连接挂在某个sub Reactor中(muduo通过round-robin算法选择一个sub Reactor)。这样该连接的所有操作都由该sub Reactor进行处理,多个连接可能被分派到多个线程中,以充分利用CPU。

muduo采用的是固定大小的Reactor poll,池的大小由用户进行设置,通常所有Reactor的个数应该等于CPU的数目。这样程序的总体处理能力不会随连接数增加而下降。由于一个连接完全由一个线程管理,那么请求的顺序性有保证,突发请求也不会占满所有CPU。把IO分配个多给线程,防止出现一个Reactor的处理能力饱和。

小规模计算可以在当前IO线程完成并发回结果,从而降低响应的延迟。如果需要大规模计算,可以再交给一个线程池让其进行处理,从而防止阻塞当前sub Reactor导致响应变慢。

如果TCP连接有优先级之分,可以将高优先级的连接放在一个单独的sub Reactor来处理,从而避免优先级反转。

muduo网络库环境搭建

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

使用muduo实现echo服务器

由于网络库封装了网络IO代码,所以不同的服务器的区别主要在于业务逻辑代码的不同。echo服务器简单地将来自客户端的数据回发给客户端,应该是业务逻辑最简单的服务器了,通过了解如何使用muduo网络库实现echo服务器有助于我们了解使用muduo网络库的基本方法,如果需要对网络部分进行优化就需要深入源码了解muduo网络库的实现原理,本文不详细涉及这部分(以后可能会更新关于muduo源码剖析的博客)。

使用muduo网络库我们需要组合TcpServer类,一般还需要保存EventLoop指针。EventLoop负责管理事件循环(epoll),TcpServer负责管理主Reactor(Acceptor管理连接socket)和从Reactors(EventLoopThreadPool管理客户端socket)以及对于每种事件的回调,这些回调会被合适的地方调用(对应事件发生的时候)。我们需要给TcpServer传入base loop、监听端口(和IP地址,一般是0.0.0.0)、服务器名称(打印日志),并且设置各种事件的回调,也就是在这里我们填入业务逻辑。


头文件EchoServer.h

// Copyright(C), Edward-Elric233
// Author: Edward-Elric233
// Version: 1.0
// Date: 2022/7/11
// Description:
#ifndef CHATSERVER_ECHOSERVER_H
#define CHATSERVER_ECHOSERVER_H#include "muduo/net/TcpServer.h"
#include "muduo/net/EventLoop.h"
#include "muduo/net/InetAddress.h"
#include "muduo/net/TcpConnection.h"
#include <string>namespace edward {class EchoServer {using TcpServer = muduo::net::TcpServer;using EventLoop = muduo::net::EventLoop;using InetAddress = muduo::net::InetAddress;using TcpConnectionPtr = muduo::net::TcpConnectionPtr;using Buffer = muduo::net::Buffer;using Timestamp = muduo::Timestamp;TcpServer tcpServer_;EventLoop *loop_;void onConnectionCallback(const TcpConnectionPtr& conn);void onMessageCallback(const TcpConnectionPtr& conn, Buffer* buffer, Timestamp timestamp);public:EchoServer(EventLoop *loop, const InetAddress& address, const std::string &name);void start();};}#endif //CHATSERVER_ECHOSERVER_H

实现文件EchoServer.cpp

// Copyright(C), Edward-Elric233
// Author: Edward-Elric233
// Version: 1.0
// Date: 2022/7/11
// Description:
#include "EchoServer.h"
#include "utils.h"
#include <functional>namespace edward {using namespace std::placeholders;EchoServer::EchoServer(EventLoop *loop, const InetAddress& address, const std::string &name): tcpServer_(loop, address, name), loop_(loop) {//使用绑定器设置回调tcpServer_.setConnectionCallback(std::bind(&EchoServer::onConnectionCallback, this, _1));tcpServer_.setMessageCallback(std::bind(&EchoServer::onMessageCallback, this, _1, _2, _3));//根据本机的核数设置线程/Reactor数量,如果不设置默认为1个tcpServer_.setThreadNum(std::thread::hardware_concurrency());
}//有新连接时的回调void EchoServer::onConnectionCallback(const TcpConnectionPtr& conn) {if (conn->connected()) {} else {}}//连接上有消息到来时的回调void EchoServer::onMessageCallback(const TcpConnectionPtr& conn, Buffer* buffer, Timestamp timestamp) {std::string msg = buffer->retrieveAllAsString();print(conn->peerAddress().toIpPort(), ":[", msg, "]at", timestamp.toFormattedString());conn->send(msg);}void EchoServer::start() {tcpServer_.start();  //使用epoll_ctl将连接socket放在loop上进行监听并设置对应的回调}}

我们将回调都设置为成员函数,这样做的好处是我们往往要在回调中访问其他系统资源,成员函数可以访问数据成员避免传参。

测试文件test.cpp

#include "EchoServer.h"
void test_EchoServer() {muduo::net::EventLoop loop;edward::EchoServer echoServer(&loop, muduo::net::InetAddress(6789), "EchoServer");echoServer.start();loop.loop();return;
}

测试结果

20220711 09:47:44.055888Z 26057 INFO TcpServer::newConnection [EchoServer] - new connection [EchoServer-0.0.0.0:6789#1] from 127.0.0.1:41678 - TcpServer.cc:80
127.0.0.1:41678 :[ Hello world
]at 20220711 09:47:49.515927
127.0.0.1:41678 :[ 123456
]at 20220711 09:47:56.117636
20220711 09:47:57.069940Z 26057 INFO TcpServer::removeConnectionInLoop [EchoServer] - connection EchoServer-0.0.0.0:6789#1 - TcpServer.cc:109

结语

掌握了muduo网络基本的用法后就可以根据需要填充业务逻辑了,如果想要了解更多就需要深入源码去了解啦。

muduo网络库使用入门相关推荐

  1. Muduo网络库核心梳理

    Muduo网络库 Muduo网络库本身并不复杂,是一个新手入门C++面向对象网络编程的经典实战项目.但是,新手在刚刚上手读代码的时候,非常容易陷入代码的汪洋大海,迷失方向.本文旨在简要梳理Muduo网 ...

  2. muduo网络库学习(八)事件驱动循环线程池EventLoopThreadPool

    muduo是支持多线程的网络库,在muduo网络库学习(七)用于创建服务器的类TcpServer中也提及了TcpServer中有一个事件驱动循环线程池,线程池中存在大量线程,每个线程运行一个Event ...

  3. muduo网络库学习(七)用于创建服务器的类TcpServer

    目前为止,涉及到的绝大多数操作都没有提及线程,EventLoop,Poller,Channel,Acceptor,TcpConnection,这些对象的执行都是在单独线程完成,并没有设计多线程的创建销 ...

  4. muduo网络库学习(四)事件驱动循环EventLoop

    muduo的设计采用高并发服务器框架中的one loop per thread模式,即一个线程一个事件循环. 这里的loop,其实就是muduo中的EventLoop,所以到目前为止,不管是Polle ...

  5. muduo网络库源码阅读Step by Step

    Posted on: Nov 26 2015 Categories: muduo C++ Tags: muduo 一般写服务端程序都需要有一个称手的网络库来帮我们处理琐碎的网络通信细节,比如连接的建立 ...

  6. 基于C++11的muduo网络库

    文章目录 写在前面 项目编译问题 库安装的问题 项目测试代码 关于压力测试 项目概述 muduo网络库的reactor模型 muduo的设计 muduo各个类 辅助类 NonCopyable Time ...

  7. muduo网络库源码复现笔记(十七):什么都不做的EventLoop

    Muduo网络库简介 muduo 是一个基于 Reactor 模式的现代 C++ 网络库,作者陈硕.它采用非阻塞 IO 模型,基于事件驱动和回调,原生支持多核多线程,适合编写 Linux 服务端多线程 ...

  8. muduo网络库的封装

    一.基础socket编程 网络编程的底层离不开socket,其处理流程表示如下: int sockfd = socket(AF_INET, SOCK_STREAM, 0);struct sockadd ...

  9. muduo网络库浅谈(一)

    muduo网络库浅谈(一) 序言 第一章 muduo的关键结构 class EventLoop class Channel class Poller 番外 定时任务 class Timestamp c ...

最新文章

  1. 编写MapReduce程序,统计每个买家收藏商品数量,实现统计排序功能
  2. Non Hybrid Long Read Consensus Using Local De Bruijn Graph Assembly
  3. 每天要问自己的十个问题
  4. 侧边栏配置_vscode入门:熟悉vscode和初级配置
  5. python人脸识别、人脸关键点检测、性别检测
  6. AliOS Things 硬件抽象层(HAL)对接系列2 — SPI driver porting
  7. android 恢复出厂设置 时间,Android 恢复出厂设置后,时间不能恢复为:2013年1月1日...
  8. 1.7 空间正交分解
  9. BOMHEAD display issue
  10. lnmp mysql 10061问题
  11. 音视频开发(19)---Android视频开发基础(一)
  12. 算法专题(一)1.1 希尔排序,快速排序
  13. android百度定位没反应,百度定位回调无反应,第一次能回调到数据,第二次无反应...
  14. Sauce Labs将分析和扩展调试添加到其持续测试云中
  15. 抵御风险——漫谈运维核心价值和方法论
  16. Django - 请求与响应、表单、中间件、上下文处理器
  17. SQL SERVER数据库 查询sql 多表联查 top命令
  18. 台达触摸屏编程软件_松下PLC远程编程调试流程
  19. 【图像分割】基于收缩系数的粒子群混合引力搜索算法多级图像阈值分割算法研究附matlab代码
  20. 微信小程序定制开发的几大类型

热门文章

  1. uni-app小程序授权登陆示例
  2. 基于Java健身房管理系统设计实现(源码+lw+部署文档+讲解等)
  3. 2011-CVPR - Blind deconvolution using a normalized sparsity measure
  4. 企业微信 微信开发者工具调试问题
  5. Get新技能:用C语言代码打开网页
  6. Spark原理篇之工作原理
  7. Edge浏览器经常崩溃、卡死、黑屏解决方法(解决完整性冲突/增加显卡占用)
  8. 局域网共享设置软件_一铭操作系统(国产操作系统)设置打印机局域网共享
  9. R语言acres92 region_R语言作Circos图之进阶篇:圈圈套圈圈的法门
  10. Simulink仿真入门到精通(十) S函数