[集群聊天项目] muduo网络库

目录

  • 网络服务器编程常用模型
  • 什么是muduo网络库
    • 什么是epoll
  • muduo网络库服务器编程

网络服务器编程常用模型

【方案1】 : accept + read/write
不是并发服务器

【方案2】 : accept + fork - process-pre-connection
适合并发连接数不大,计算任务工作量大于fork的开销

【方案3】 :accept + thread thread-pre-connection
比方案2的开销小了一点,但是并发造成线程堆积过多

【方案4】: muduo的网络设计:reactors in threads - one loop per thread

【方案5】 : reactors in process - one loop pre process
nginx服务器的网络模块设计,基于进程设计,采用多个Reactors充当I/O进程和工作进程,通过一把accept锁,完美解决多个Reactors的“惊群现象”

什么是muduo网络库

高并发,因此服务器要用muduo编程
在这里插入图片描述
在这里插入图片描述

方案的特点是one loop per thread(一个线程一个时间循环),有一个main reactor负载accept连接(I/O线程),然后把连接分发到某个sub reactor(采用round-robin[轮询]的方式来选择sub reactor),该连接的所用操作都在那个sub reactor所处的线程中完成,注册到某个线程的epoll事件上,那么所做的所有读写操作都在这个epoll上完成。多个连接可能被分派到多个线程中,以充分利用CPU。

Reactor poll的大小是固定的,根据CPU的数目确定。

如果有过多的耗费CPU I/O的计算任务,可以提交到创建的ThreadPool线程池中专门处理耗时的计算任
务。

// 设置EventLoop的线程个数,底层通过EventLoopThreadPool线程池管理线程类EventLoopThread
_server.setThreadNum(10);

一个Base IO thread负责accept新的连接,接收到新的连接以后,使用轮询的方式在reactor pool中找
到合适的sub reactor将这个连接挂载上去,这个连接上的所有任务都在这个sub reactor上完成。

什么是epoll

学习资料
epoll 是 Linux 内核的可扩展 I/O 事件通知机制,其最大的特点就是性能优异。
在这里插入图片描述

muduo网络库服务器编程

moduo库的使用需要链接libmuduo_base.solibmuduo_net.solibpthread.so库,我们执行的时候需要-lmuduo_net -lmuduo_base -lpthread,需要配置这些。

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

  • TcpSever : 用于编写服务器程序的
  • TcpClient : 用于编写客户端程序的

eopll + 线程池
好处:能把网络I/O的代码和业务代码区分开

业务代码的暴露主要有两个:用户的连接和断开,用户的可读写事件。我们只需要关注这两个事件怎么做,至于什么时候发生这些事情(网络库上报)以及怎么监听这些事件的发生,都是由网络库实现好的。

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

1. 组合TcpSevrer对象:不指定构造TcpServer _server;就要用默认构造,但是进入到TcpServer.h中发现TcpServer没有默认构造,因此要指定_server相应的构造,在pubilc中。不指定,ChatServer类无法创建对象。
TcpServer没有默认构造

2. 创建EventLoop事件循环对象的指针

TcpServer _server; // #1
EventLoop *_loop;  // #2 epoll

3. 明确TcpServer构造函数需要什么函数,输出ChatServer的构造函数

ChatServer(EventLoop *loop,               // 事件循环
       const InetAddress &listenAddr, // IP地址+端口
           const string &nameArg)         // 服务器的名字
    : _server(loop, listenAddr, nameArg), _loop(loop)
{}

4.在当前服务器类的构造函数中,注册处理连接的回调函数和处理读写事件的回调函数。将处理业务的代码onConnectiononMessage分离出来,和对应的Callback代码绑定到一起,其中onConnectiononMessage两个函数的参数类型和数量是根据Callback函数设置的。
在这里插入图片描述

// 给服务器注册用户连接的创建和断开回调,一旦监听到此活动,就会调用onConnection函数
// 人家的Callback函数只有一个参数,但是自己写的onConnection有两个参数,隐含一个this
// _1是参数占位符(需要using namespace placeholders;),是onConnection括号中的参数
_server.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1));
// 给服务器注册用户读写事件回调
_server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));
// **************************************************************
// 专门处理用户的连接创建和断开 epoll  listenfd accept
void onConnection(const TcpConnectionPtr &conn)
{// 放业务代码}

// 专门处理用户的读写事件
void onMessage(const TcpConnectionPtr &conn, // 连接
               Buffer *buffer,               // 缓冲区
               Timestamp time)               // 接收到数据的时间信息
{// 放业务代码}

5. 设置合适的服务端线程数,muduo库会自己分配I/O线程和worker线程

// 设置服务器端的线程数量 1个I/O线程 3个worker线程
_server.setThreadNum(4);

全部代码:

#include <muduo/net/TcpServer.h>
#include <muduo/net/TcpClient.h>
#include <iostream>
#include <functional> //绑定器在此文件中
#include <string>
using namespace std;
using namespace muduo;
using namespace muduo::net;
using namespace placeholders;

class ChatServer
{
public:
    // #3
    ChatServer(EventLoop *loop,
               const InetAddress &listenAddr,
               const string &nameArg)
        : _server(loop, listenAddr, nameArg), _loop(loop)
    {
        // #4
        _server.setConnectionCallback(std::bind(&ChatServer::onConnection, this, _1));
        _server.setMessageCallback(std::bind(&ChatServer::onMessage, this, _1, _2, _3));

        // #5
        _server.setThreadNum(4);
    }

    // 开启事件循环
    void start()
    {
        _server.start();
    }

private:
    // 专门处理用户的连接创建和断开 epoll  listenfd accept
    void onConnection(const TcpConnectionPtr &conn)
    {
        // 放业务代码
        if (conn->connected())
        {
            cout << conn->peerAddress().toIpPort() << " -> " << conn->localAddress().toIpPort() << " state:online" << endl;
        }
        else
        {
            cout << conn->peerAddress().toIpPort() << " -> " << conn->localAddress().toIpPort() << " state:offline" << endl;
            conn->shutdown(); // close(fd)
            // _loop->quit();
        }
    }

    // 专门处理用户的读写事件
    void onMessage(const TcpConnectionPtr &conn,
                   Buffer *buffer,
                   Timestamp time)
    {
        // 放业务代码
        string buff = buffer->retrieveAllAsString();
        cout << "recv data:" << buff << "time: " << time.toString() << endl;
        conn->send(buff);
    }

    TcpServer _server;
    EventLoop *_loop;
};

int main()
{
    EventLoop loop; // epoll
    InetAddress addr("127.0.0.1", 6000);
    ChatServer server(&loop, addr, "ChatServer");

    server.start(); // 启动服务, listenfd epoll_atl=>epoll
    loop.loop();    // epoll_wait以阻塞方式等待新用户链接,已连接用户的读写事件等操作

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Centos的一些基础命令

CentOS是一个基于开源代码构建的免费Linux发行版&#xff0c;它由Red Hat Enterprise Linux (RHEL) 的源代码重新编译而成。由于 CentOS是基于RHEL构建的&#xff0c;因此它与RHEL具有非常类似的特性和功能&#xff0c;包括稳定性、安全性和可靠性。并且大部分的 Linux 命令在C…

Apache Doris 2.x 版本【保姆级】安装+使用教程

Doris简介 Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库&#xff0c;以极速易用的特点被人们所熟知&#xff0c;仅需亚秒级响应时间即可返回海量数据下的查询结果&#xff0c;不仅可以支持高并发的点查询场景&#xff0c;也能支持高吞吐的复杂分析场景。基于…

COOIS 生产订单显示系统增强

需求说明&#xff1a;订单系统显示页面新增批量打印功能 增强点&#xff1a;CL_COIS_DISP_LIST_NAVIGATION -->TOOLBAR方法中新增隐式增强添加自定义打印按钮 增强点&#xff1a;BADI-->WORKORDER_INFOSYSTEM新增增强实施 实现位置&#xff1a;IF_EX_WORKORDER_INFOSYS…

频裂变加群推广强制分享引流源码

视频裂变加群推广强制分享引流源码&#xff0c;用户达到观看次数后需要分享给好友或者群,好友必须点击推广链接后才会增加观看次数。 引导用户转发QV分享,达到快速裂变引流的效果&#xff01; 视频裂变推广程序&#xff0c;强制分享链接&#xff0c;引导用户转发&#xff0c;…

数据库MySQL的初级基础操作

文章目录 1. 介绍2. 数据库相关概念3. 启动4. 数据模型5. SQL6. DDL数据库DDL-表操作DDL-表操作-数据类型DDL-表操作-修改DDL-表操作-删除 7. 图形化界面工具DataGrip8. DML(数据操作语言)DML-添加数据DML-修改数据 9. DQL&#xff08;数据查询语言&#xff09;基本查询条件查询…

MemFire案例-政务应急物联网实时监测预警项目

客户背景 党的十八大以来&#xff0c;中央多次就应急管理工作做出重要指示&#xff1a;要求坚持以防为主、防抗救相结合&#xff0c;全面提升综合防灾能力&#xff1b;坚持生命至上、安全第一&#xff0c;完善安全生产责任制&#xff0c;坚决遏制重特大安全事故。 面对新形势…

小白学习SpringCloud之Eureka

前言 需要搭建springcloud项目&#xff0c;eureka是其中的一个模块&#xff0c;依赖主要继承父依赖 学习视频&#xff1a;b站狂神说 便于理解,我修改了本地域名》这里!!! 127.0.0.1 eureka7001.com 127.0.0.1 eureka7002.com 127.0.0.1 eureka7003.comEureka入门案例 eureka…

Maven的仓库、周期和插件

一、简介 随着各公司的Java项目入库方式由老的Ant改为Maven后&#xff0c;相信大家对Maven已经有了个基本的熟悉。但是在实际的使用、入库过程中&#xff0c;笔者发现挺多人对Maven的一些基本知识还缺乏了解&#xff0c;因此在此处跟大家简单地聊下Maven的相关内容&#xff0c…

如何把经验变成可以销售的“知识产品”?

知识付费&#xff0c;很多人想做&#xff0c;但是不知道如何把自己在某方面的“经验”&#xff0c;变成一个“知识产品”&#xff0c;那么这篇文章&#xff0c;我们就来聊聊如何从0打造一个知识产品 非常简单&#xff0c;一共六个步骤&#xff1a; 第一步&#xff1a;取名字&…

【深度学习】StabelDiffusion,Lora训练过程,秋叶包,Linux,SDXL Lora训练

文章目录 一、环境搭建指南二、个性化安装流程三、启动应用四、打开web五、开始训练 19.27服务器 一、环境搭建指南 打造一个高效且友好的开发环境&#xff0c;我们推荐使用以下简洁明了的中文资源&#xff1a; 项目源码获取&#xff1a; 通过以下命令轻松克隆项目及所有子模…

(一)Dataframes安装与类型 #Julia数据分析 #CDA学习打卡

目录 一. Julia简介 二. Dataframe构造方法 1&#xff09;访问列的方式 &#xff08;a&#xff09;判断严格相等 i. 切片严格相等是true ii. 复制严格相等是false &#xff08;b&#xff09;判断相等 i. 切片相等是true ii. 复制相等是true 2&#xff09;获取列名称 …

【Camera KMD ISP SubSystem笔记】CAM SYNC与DRQ③

DRQ什么时候调度Node去填写dependency ::Pipeline调度Node的sequenceId 0执行 Pipeline::ProcessRequest() { for (UINT nodeIndex 0; nodeIndex < m_orderedNodeCount ; nodeIndex) m_pDeferredRequestQueue->AddDef…

ROM修改进阶教程------如何去除安卓机型系统的开机向导 几种操作步骤解析

在和很多工作室定制化系统中。手机在第一次启动的时候系统都会进入设置向导,虽然可以设置手机的基本配置。但有很多客户需要去除手机的开机向导来缩短开机时间。确保手机直接进入工作状态。那么今天的教程针去除对开机向导的几种方法做个解析。机型很多版本不同。操作也有不同…

JS实现对用户名、密码进行正则表达式判断,网页跳转

目标&#xff1a;使用JS实现对用户名和密码进行正则表达式判断&#xff0c;用户名和密码正确时&#xff0c;进行网页跳转。 用户名、密码的正则表达式检验 HTML代码&#xff1a; <button type"submit" id"login-btn" /*onclick"login();alidate…

四川易点慧电子商务:抖音小店引领潮流,先进模式打造电商新标杆

在当下数字化浪潮中&#xff0c;电子商务行业如日中天&#xff0c;四川易点慧电子商务有限公司以其独特的视角和前瞻性的战略布局&#xff0c;成功在抖音小店领域崭露头角&#xff0c;成为行业内的佼佼者。本文将深入剖析四川易点慧电子商务的成功秘诀&#xff0c;以及其在抖音…

【openLooKeng-1.10.0集群环境安装部署】

openLooKeng-1.10.0集群环境安装部署 一、摘要二、正文1. 环境说明2. 集群拓扑图3. 安装过程(以root用户安装)3.1 在Coordinator和Worker两个节点都需要安装jdk1.8+3.2 在Coordinator上安装配置openLooKeng3.3 在Worker节点上进行配置openLooKeng3.4 在Coordinator节点上先启…

Spring Boot集成Redisson实现延迟队列

项目场景&#xff1a; 在电商、支付等领域&#xff0c;往往会有这样的场景&#xff0c;用户下单后放弃支付了&#xff0c;那这笔订单会在指定的时间段后进行关闭操作&#xff0c;细心的你一定发现了像某宝、某东都有这样的逻辑&#xff0c;而且时间很准确&#xff0c;误差在1s内…

OceanBase单机版安装体验

前情提要 上周OceanBase开发者大会过后&#xff0c;作为观察员也来体验一下OB的安装。业内有某个国产安装用了两周&#xff0c;这种其实有点劝退了。话说就是10年前&#xff0c;没搞过Oracle的人也不用两周安装一个数据库啊。今天看看OB的&#xff08;一体化&#xff09;安装。…

【震撼揭秘】Sentinel:一文读懂,那些让开发者“拍案叫绝”的核心特性!

关注微信公众号 “程序员小胖” 每日技术干货&#xff0c;第一时间送达&#xff01; 引言 在微服务架构中&#xff0c;流量治理是确保系统稳定性和高可用性的关键。Sentinel作为一项强大的流量控制组件&#xff0c;为我们提供了完善的解决方案。本文将带您走进Sentinel的世界…

第11章 Android特色开发——基于位置的服务

第11章 Android特色开发——基于位置的服务 本章中&#xff0c;将要学习一些全新的Android技术&#xff0c;这些技术有别于传统的PC或Web领域的应用技术&#xff0c;是只有在移动设备上才能实现的。 基于位置的服务&#xff08;Location Based Service&#xff09;。由于移动…