muduo库TcpServer模块详解

news2025/5/22 23:48:01

Muduo库核心模块——TcpServer

Muduo库的TcpServer模块是一个基于Reactor模式的高性能TCP服务端实现,负责管理监听端口、接受新连接、分发IO事件及处理连接生命周期。


一、核心组件与职责

  1. Acceptor
    • 监听指定端口,接受新连接,通过epoll监听listenfd的可读事件(表示新连接到达)。
    • 内部封装socketbind操作,支持SO_REUSEADDR选项避免端口占用。
    • 新连接到达时,调用TcpServer的回调创建TcpConnection对象。
  2. EventLoop
    • 主事件循环(运行在主线程),处理Acceptor的事件及定时任务。
    • 采用“one loop per thread”模型,确保线程安全,所有操作通过EventLoop的任务队列跨线程调度。
  3. EventLoopThreadPool
    • IO线程池,管理多个子EventLoop,提升并发处理能力。
    • 新连接通过轮询或哈希策略分配到子EventLoop,实现负载均衡。
  4. TcpConnection
    • 封装一条TCP连接,管理send/recv缓冲区、处理读写事件及连接状态(连接中/已断开)。
    • 通过Channel注册到所属EventLoop,监听socket的可读/可写事件。
  5. 回调机制
    • 用户可设置的关键回调:
      • ConnectionCallback:连接建立或关闭时触发。
      • MessageCallback:接收到数据时调用,传递数据缓冲区及时间戳。
      • WriteCompleteCallback:数据发送完成时通知。

二、工作流程

  1. 启动服务器
    • 用户调用TcpServer::start(),启动EventLoopThreadPoolAcceptor开始监听。
    • EventLoop进入循环,等待事件。
  2. 接受新连接
    • Acceptor监听到新连接,创建connfd,构造TcpConnection对象。
    • 为新连接分配IO线程(从EventLoopThreadPool中选择一个子EventLoop)。
    • TcpConnection的socket注册到子EventLoopepoll中。
  3. 处理IO事件
    • 读事件:子EventLoop触发可读事件,TcpConnection读取数据至缓冲区,调用用户MessageCallback
    • 写事件:发送缓冲区中的数据,写完成后触发WriteCompleteCallback
    • 错误处理:处理EPOLLERR等异常,关闭连接并通知用户。
  4. 连接关闭
    • 主动关闭:调用TcpConnection::shutdown(),等待数据发送完毕。
    • 被动关闭:接收到EOF或错误,触发handleClose(),移除连接并销毁资源。

三、线程安全与资源管理

  1. 跨线程调度
    • 通过EventLoop::runInLoop()确保回调在正确的线程执行,避免竞态条件。
    • 示例:主线程接受连接后,通过ioLoop->runInLoop()TcpConnection添加到子线程。
  2. 连接生命周期
    • 使用shared_ptr<TcpConnection>管理连接对象,引用计数确保回调期间对象存活。
    • 连接关闭时,通过TcpServer::removeConnection()从连接列表移除,并延迟销毁(防止析构在回调中触发)。
  3. 资源释放
    • TcpServer维护ConnectionMap跟踪所有活跃连接,析构时自动关闭所有连接。

四、性能优化策略

  1. 零拷贝优化
    • 使用readv/writev分散读写,减少内存拷贝。
    • 应用层缓冲区设计,避免频繁系统调用。
  2. LT模式与边缘触发
    • 采用epoll的LT(水平触发)模式,确保数据未处理时会持续通知,简化编程。
    • 非阻塞IO配合EAGAIN处理,避免线程阻塞。
  3. 高效线程模型
    • 主线程仅处理新连接,IO线程分担数据读写,充分发挥多核优势。

五、示例代码

#include <muduo/net/TcpServer.h>
#include <muduo/net/EventLoop.h>

void onConnection(const muduo::net::TcpConnectionPtr& conn) {
    if (conn->connected()) {
        printf("New connection: %s\n", conn->peerAddress().toIpPort().c_str());
    } else {
        printf("Connection closed: %s\n", conn->peerAddress().toIpPort().c_str());
    }
}

void onMessage(const muduo::net::TcpConnectionPtr& conn,
               muduo::net::Buffer* buf,
               muduo::Timestamp time) {
    printf("Received %zd bytes: %s\n", buf->readableBytes(), buf->retrieveAllAsString().c_str());
}

int main() {
    muduo::net::EventLoop loop;
    muduo::net::InetAddress listenAddr(8888);
    muduo::net::TcpServer server(&loop, listenAddr, "ExampleServer");
    
    server.setConnectionCallback(onConnection);
    server.setMessageCallback(onMessage);
    server.setThreadNum(4);  // 4 IO threads
    server.start();
    
    loop.loop();  // Block here
}

六、关键设计思想

  1. Reactor模式:事件驱动,非阻塞IO,提升吞吐量。
  2. 资源局部性:每个连接绑定到固定IO线程,减少锁竞争。
  3. 回调抽象:用户聚焦业务逻辑,网络细节由库封装。
  4. RAII管理:智能指针自动管理资源,防止泄漏。

通过上述机制,Muduo的TcpServer模块实现了高并发、低延迟的TCP服务端,适用于需要处理大量持久连接的场景(如即时通讯、实时数据推送等)。

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

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

相关文章

Java 代码生成工具:如何快速构建项目骨架?

Java 代码生成工具&#xff1a;如何快速构建项目骨架&#xff1f; 在 Java 项目开发过程中&#xff0c;构建项目骨架是一项繁琐但又基础重要的工作。幸运的是&#xff0c;Java 领域有许多代码生成工具可以帮助我们快速完成这一任务&#xff0c;大大提高开发效率。 一、代码生…

Nginx核心服务

一&#xff0e;正向代理 正向代理&#xff08;Forward Proxy&#xff09;‌是一种位于客户端和原始服务器之间的代理服务器&#xff0c;其主要作用是将客户端的请求转发给目标服务器&#xff0c;并将响应返回给客户端 Nginx 的 正向代理 充当客户端的“中间人”&#xff0c;代…

第22天-Python ttkbootstrap 界面美化指南

环境安装 pip install ttkbootstrap 示例1:基础主题切换器 import ttkbootstrap as ttk from ttkbootstrap.constants import *def create_theme_switcher():root = ttk.Window(title="主题切换器", themename="cosmo")def change_theme():selected = t…

Kubernetes控制平面组件:Kubelet详解(七):容器网络接口 CNI

云原生学习路线导航页&#xff08;持续更新中&#xff09; kubernetes学习系列快捷链接 Kubernetes架构原则和对象设计&#xff08;一&#xff09;Kubernetes架构原则和对象设计&#xff08;二&#xff09;Kubernetes架构原则和对象设计&#xff08;三&#xff09;Kubernetes控…

web应用技术第6次课---Apifox的使用

Apifox - API 文档、调试、Mock、测试一体化协作平台。拥有接口文档管理、接口调试、Mock、自动化测试等功能&#xff0c;接口开发、测试、联调效率&#xff0c;提升 10 倍。最好用的接口文档管理工具&#xff0c;接口自动化测试工具。 第一个问题&#xff1a;为什么需要用Apif…

Redis队列与Pub/Sub方案全解析:原理、对比与实战性能测试

一、为什么选择Redis实现消息队列&#xff1f; Redis凭借其内存级操作&#xff08;微秒级响应&#xff09;、丰富的数据结构以及持久化能力&#xff0c;成为构建高性能消息队列的热门选择。相比传统消息队列&#xff08;如Kafka/RabbitMQ&#xff09;&#xff0c;Redis在以下场…

OBOO鸥柏丨AI数字人触摸屏查询触控人脸识别语音交互一体机上市

OBOO鸥柏丨AI数字人触摸屏查询触控人脸识别语音交互一体机上市分析 OBOO鸥柏品牌推出的AI数字人触摸屏查询触控人脸识别语音交互一体机&#xff0c;是其在智能交互设备领域的又一创新产品。该一体机整合了触摸屏查询、AI人脸识别、AI声源定位语音麦克风&#xff0c;触控交互以…

第5天-python饼图绘制

一、基础饼图绘制(Matplotlib) 1. 环境准备 python 复制 下载 pip install matplotlib numpy 2. 基础饼图代码 python 复制 下载 import matplotlib.pyplot as plt# 数据准备 labels = [1, 2, 3, 4] sizes = [30, 25, 15, 30] # 各部分占比(总和建议100) colors…

2023 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛) 解题报告 | 珂学家

前言 题解 2023 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(国赛)。 vp了下&#xff0c;题目挺好的&#xff0c;难度也适中&#xff0c;但是彻底红温了。 第二题&#xff0c;题意不是那么清晰&#xff0c; M i n ( K 1 , K 2 ) Min(K_1, K_2) Min(K1​,K2​)容易求&#x…

LabVIEW风机状态实时监测

在当今电子设备高度集成化的时代&#xff0c;设备散热成为关键问题。许多大型设备机箱常采用多个风机协同散热&#xff0c;确保系统稳定运行。一旦风机出现故障&#xff0c;若不能及时察觉&#xff0c;可能导致设备损坏&#xff0c;造成巨大损失。为满足对机箱内风机状态实时监…

十一、面向对象底层逻辑-Dubbo过滤器Filter接口

一、引言&#xff1a;分布式系统中的可观测性与治理基石 在分布式服务调用链路中&#xff0c;如何在服务调用前后植入通用逻辑&#xff08;如日志记录、权限校验、性能监控等&#xff09;&#xff0c;是构建可观测、可治理系统的关键需求。Dubbo通过Filter接口实现了面向切面编…

linux安装nginx和前端部署vue项目

1、打包前端项目 npm run build 执行完后会在根目录下生成一个dist文件夹&#xff0c;这个dist文件夹就是我们后面要部署到nginx的东西。 2、将dist文件夹上传到服务器中 自己建一个目录&#xff0c;上传即可&#xff08;尽量不要在root目录下&#xff0c;可能涉及权限问题…

软件设计师“数据流图”真题考点分析——求三连

数据流图考点分析 1. 考点分值占比与趋势分析 综合知识题分值统计表 年份考题数量分值分值占比考察重点2018111.33%数据流图基本元素2019222.67%数据流图绘制原则2020111.33%数据流图与控制流图的区别2021334.00%数据字典与数据流图的关系2022222.67%分层数据流图的分解原则…

基于R语言的贝叶斯网络模型实践技术应用:开启科研新视角

在现代科研领域&#xff0c;变量间的因果关系推断是生态学、环境科学、医学等多学科研究的核心问题。然而&#xff0c;传统的统计学方法往往只能揭示变量间的相关关系&#xff0c;而非因果关系。贝叶斯网络作为一种结合图论与统计学理论的新型模型&#xff0c;不仅能够统合多种…

【Git】远程操作

Git 是一个分布式版本控制系统 可以简单理解为&#xff0c;每个人的电脑上都是一个完整的版本库&#xff0c;这样在工作时&#xff0c;就不需要联网 了&#xff0c;因为版本库就在自己的电脑上。 因此&#xff0c; 多个人协作的方式&#xff0c;譬如说甲在自己的电脑上改了文件…

DeepSpeed简介及加速模型训练

DeepSpeed是由微软开发的开源深度学习优化框架&#xff0c;专注于大规模模型的高效训练与推理。其核心目标是通过系统级优化技术降低显存占用、提升计算效率&#xff0c;并支持千亿级参数的模型训练。 官网链接&#xff1a;deepspeed 训练代码下载&#xff1a;git代码 一、De…

openlayer:10点击地图上某些省份利用Overlay实现提示省份名称

实现点击地图上的省份&#xff0c;在点击经纬度坐标位置附近利用Overlay实现提示框提示相关省份名称。本文介绍了如何通过OpenLayers库实现点击地图上的省份&#xff0c;并在点击的经纬度坐标位置附近显示提示框&#xff0c;提示相关省份名称。首先&#xff0c;定义了两个全局变…

upload-labs通关笔记-第13关 文件上传之白名单POST法

目录 一、白名单过滤 二、%00截断 1.截断原理 2、截断条件 &#xff08;1&#xff09;PHP版本 < 5.3.4 &#xff08;2&#xff09;magic_quotes_gpc配置为Off &#xff08;3&#xff09;代码逻辑存在缺陷 三、源码分析 1、代码审计 &#xff08;1&#xff09;文件…

数据库健康监测器(BHM)实战:如何通过 HTML 报告识别潜在问题

在数据库运维中,健康监测是保障系统稳定性与性能的关键环节。通过 HTML 报告,开发者可以直观查看数据库的运行状态、资源使用情况与潜在风险。 本文将围绕 数据库健康监测器(Database Health Monitor, BHM) 的核心功能展开分析,结合 Prometheus + Grafana + MySQL Export…

Oracle 11g 单实例使用+asm修改主机名导致ORA-29701 故障分析

解决 把服务器名修改为原来的&#xff0c;重启服务器。 故障 建表空间失败。 分析 查看告警日志 ORA-1119 signalled during: create tablespace splex datafile ‘DATA’ size 2000M… Tue May 20 18:04:28 2025 create tablespace splex datafile ‘DATA/option/dataf…