Muduo:(0) 架构与接口总览

一、项目概述

1.1 项目简介

mymuduo 是一个基于 Reactor 模式的高性能 C++ 网络库,基于陈硕的 muduo 网络库进行 C++ 重构。它提供了简洁的 API,支持 TCP 服务器和客户端开发,具有以下特点:

  • 事件驱动:基于 epoll 的高效 I/O 多路复用
  • 多线程支持:主从 Reactor 模式,充分利用多核 CPU
  • 异步编程:基于回调的异步编程模型

1.2 核心特性

特性 说明
Reactor 模式 事件驱动的并发模型
One Loop Per Thread 每个线程一个事件循环
非阻塞 I/O 全程非阻塞操作
连接管理 自动管理连接生命周期
缓冲区管理 高效的数据缓冲机制
日志系统 灵活的日志记录

1.3 项目结构

复制代码
mymuduo/
├── include/              # 头文件目录
│   ├── EventLoop.h
│   ├── Channel.h
│   ├── Poller.h
│   ├── EPollPoller.h
│   ├── TcpServer.h
│   ├── TcpConnection.h
│   ├── Acceptor.h
│   ├── EventLoopThreadPool.h
│   ├── EventLoopThread.h
│   ├── Buffer.h
│   ├── Logger.h
│   ├── LogStream.h
│   ├── Thread.h
│   ├── Socket.h
│   ├── InetAddress.h
│   ├── Timestamp.h
│   ├── NonCopyable.h
│   ├── CurrentThread.h
│   └── Callbacks.h
├── src/                  # 源文件目录
│   ├── EventLoop.cpp
│   ├── Channel.cpp
│   ├── Poller.cpp
│   ├── EPollPoller.cpp
│   ├── DefaultPoller.cpp
│   ├── TcpServer.cpp
│   ├── TcpConnection.cpp
│   ├── Acceptor.cpp
│   ├── EventLoopThreadPool.cpp
│   ├── EventLoopThread.cpp
│   ├── Logger.cpp
│   ├── LogStream.cpp
│   ├── Thread.cpp
│   ├── Socket.cpp
│   ├── InetAddress.cpp
│   ├── Timestamp.cpp
│   └── CurrentThread.cpp
├── example/              # 示例代码
│   └── EchoServer.cpp
├── readme/               # 文档目录
│   └── *.md
└── build/                # 构建目录

二、整体架构设计

2.1 架构总览

mymuduo 采用分层架构设计:

复制代码
+--------------------------------------------------+
|                   应用层                          |
|            (用户代码 / EchoServer)               |
+--------------------------------------------------+
                        |
+--------------------------------------------------+
|                   服务器层                        |
|              TcpServer / TcpConnection           |
+--------------------------------------------------+
                        |
+--------------------------------------------------+
|                   事件层                          |
|         EventLoop / Channel / Poller             |
+--------------------------------------------------+
                        |
+--------------------------------------------------+
|                   工具层                          |
|    Buffer / Logger / Thread / Socket / Timestamp |
+--------------------------------------------------+

2.2 Reactor 模式

mymuduo 实现了 Reactor 模式,核心组件包括:

复制代码
+--------------------------------------------------+
|                   Reactor 模式                    |
+--------------------------------------------------+
|                                                   |
|  +-------------+     +-------------+              |
|  |   Handle    |---->|  Synchronous|              |
|  |  (fd)       |     |  Event Demux|              |
|  +-------------+     |  (Poller)   |              |
|                      +-------------+              |
|                             |                     |
|                             v                     |
|                      +-------------+              |
|                      |  Initiation |              |
|                      |  Dispatcher |              |
|                      |  (EventLoop)|              |
|                      +-------------+              |
|                             |                     |
|                             v                     |
|                      +-------------+              |
|                      |Event Handler|              |
|                      |  (Channel)  |              |
|                      +-------------+              |
|                             |                     |
|                             v                     |
|                      +-------------+              |
|                      |  Callbacks  |              |
|                      +-------------+              |
|                                                   |
+--------------------------------------------------+

2.3 主从 Reactor 线程模型

复制代码
+--------------------------------------------------+
|                主从 Reactor 模型                  |
+--------------------------------------------------+
|                                                   |
|  +------------------+                             |
|  |    mainReactor   |  (主线程)                   |
|  |    (baseLoop)    |                             |
|  +--------+---------+                             |
|           |                                       |
|           | 新连接                                |
|           v                                       |
|  +------------------+                             |
|  |    Acceptor      |                             |
|  +--------+---------+                             |
|           |                                       |
|           | 分发连接                              |
|           v                                       |
|  +--------+--------+--------+--------+           |
|  |        |        |        |        |           |
|  v        v        v        v        v           |
| +----+  +----+  +----+  +----+  +----+          |
| |sub |  |sub |  |sub |  |sub |  |sub |          |
| |Reactor|Reactor|Reactor|Reactor|Reactor|       |
| +----+  +----+  +----+  +----+  +----+          |
|   |        |        |        |        |          |
|   v        v        v        v        v          |
| +----+  +----+  +----+  +----+  +----+          |
| |Conn|  |Conn|  |Conn|  |Conn|  |Conn|          |
| +----+  +----+  +----+  +----+  +----+          |
|                                                   |
+--------------------------------------------------+

2.4 数据流向

复制代码
接收数据流:
+----------+     +----------+     +----------+     +----------+
|  Client  |---->|  socket  |---->|  Channel |---->| EventLoop|
+----------+     +----------+     +----------+     +----------+
                                                        |
                                                        v
+----------+     +----------+     +----------+     +----------+
| 用户回调  |<----|MessageCb |<----|inputBuffer|<---|handleRead|
+----------+     +----------+     +----------+     +----------+

发送数据流:
+----------+     +----------+     +----------+     +----------+
| 用户代码  |---->|  send()  |---->|outputBuffer|-->|handleWrite|
+----------+     +----------+     +----------+     +----------+
                                                        |
                                                        v
+----------+     +----------+     +----------+     +----------+
|  Client  |<----|  socket  |<----|  Channel |<----| EventLoop|
+----------+     +----------+     +----------+     +----------+

三、技术选型

3.1 核心技术

技术 选择 原因
I/O 多路复用 epoll Linux 高性能实现
线程模型 std::thread C++11 标准,跨平台
回调机制 std::function 类型安全,灵活
智能指针 std::shared_ptr 自动内存管理
原子操作 std::atomic 无锁编程支持

3.2 系统调用

系统调用 用途
epoll_create1 创建 epoll 实例
epoll_ctl 控制 epoll 实例
epoll_wait 等待事件
eventfd 线程间通信
accept4 接受连接
readv 分散读取
sendfile 零拷贝发送

3.3 设计模式

模式 应用场景
Reactor 事件驱动架构
RAII 资源管理
策略模式 Poller 抽象
观察者模式 回调机制
工厂模式 Poller 创建

四、模块职责与协作

4.1 核心模块

4.1.1 EventLoop

职责

  • 事件循环管理
  • 任务调度
  • 线程绑定

协作关系

复制代码
EventLoop
    |
    +-- Poller (I/O 多路复用)
    |
    +-- Channel (事件分发)
    |
    +-- wakeupFd (线程唤醒)
4.1.2 Channel

职责

  • 封装 fd 和事件
  • 管理事件回调
  • 事件状态跟踪

协作关系

复制代码
Channel
    |
    +-- EventLoop (所属循环)
    |
    +-- Poller (事件注册)
    |
    +-- TcpConnection (回调设置)
4.1.3 Poller / EPollPoller

职责

  • I/O 多路复用
  • Channel 管理
  • 事件轮询

协作关系

复制代码
Poller (抽象基类)
    |
    +-- EPollPoller (epoll 实现)
    |
    +-- ChannelMap (fd -> Channel)
4.1.4 TcpServer

职责

  • 服务器管理
  • 连接管理
  • 回调管理

协作关系

复制代码
TcpServer
    |
    +-- Acceptor (接受连接)
    |
    +-- EventLoopThreadPool (线程池)
    |
    +-- ConnectionMap (连接管理)
4.1.5 TcpConnection

职责

  • 连接状态管理
  • 数据收发
  • 事件处理

协作关系

复制代码
TcpConnection
    |
    +-- Socket (套接字)
    |
    +-- Channel (事件通道)
    |
    +-- Buffer (数据缓冲)
4.1.6 Acceptor

职责

  • 监听 socket 管理
  • 接受新连接
  • 回调通知

协作关系

复制代码
Acceptor
    |
    +-- Socket (监听 socket)
    |
    +-- Channel (监听事件)
    |
    +-- TcpServer (新连接回调)
4.1.7 EventLoopThreadPool

职责

  • 线程池管理
  • 负载均衡
  • EventLoop 分发

协作关系

复制代码
EventLoopThreadPool
    |
    +-- EventLoopThread[] (IO 线程)
    |
    +-- baseLoop (主循环)
4.1.8 Buffer

职责

  • 数据缓冲
  • 高效读写
  • 自动扩容

协作关系

复制代码
Buffer
    |
    +-- TcpConnection (输入/输出缓冲)
    |
    +-- readv (分散读取)

4.2 模块依赖图

复制代码
                    +----------------+
                    |   TcpServer    |
                    +-------+--------+
                            |
            +---------------+---------------+
            |               |               |
    +-------v-------+ +-----v-----+ +-------v-------+
    |   Acceptor    | |Thread Pool| | ConnectionMap |
    +-------+-------+ +-----+-----+ +-------+-------+
            |               |               |
            |               |               |
    +-------v-------+       |       +-------v-------+
    |   Socket      |       |       | TcpConnection |
    +-------+-------+       |       +-------+-------+
            |               |               |
            v               v               v
    +----------------+ +-----------+ +---------------+
    |    Channel     | |EventLoop  | | Buffer        |
    +----------------+ |   Thread  | | Socket        |
            |          +-----------+ | Channel       |
            v                |       +---------------+
    +----------------+       |
    |    EventLoop   |<------+
    +----------------+
            |
            v
    +----------------+
    |     Poller     |
    +----------------+

五、项目使用

5.1 Echo 服务器示例

cpp 复制代码
#include "TcpServer.h"
#include "EventLoop.h"
#include "LogStream.h"
#include <iostream>

using namespace mymuduo;

class EchoServer {
public:
    EchoServer(EventLoop *loop, const InetAddress &addr, const std::string &name)
        : server_(loop, addr, name), loop_(loop) {
        
        server_.setConnectionCallback(
            std::bind(&EchoServer::onConnection, this, std::placeholders::_1));
        server_.setMessageCallback(
            std::bind(&EchoServer::onMessage, this, 
                      std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
        server_.setThreadNum(3);
    }

    void start() { server_.start(); }

private:
    void onConnection(const TcpConnectionPtr &conn) {
        if (conn->connected()) {
            LOG_INFO << "Connection UP : " << conn->peerAddress().toIpPort();
        } else {
            LOG_INFO << "Connection DOWN : " << conn->peerAddress().toIpPort();
        }
    }

    void onMessage(const TcpConnectionPtr &conn, Buffer *buf, Timestamp time) {
        std::string msg = buf->retrieveAllAsString();
        conn->send(msg);
    }

    TcpServer server_;
    EventLoop *loop_;
};

int main() {
    g_logger = new Logger();
    g_logger->SetLogLevel(kInfo);
    
    EventLoop loop;
    InetAddress addr(8080);
    EchoServer server(&loop, addr, "EchoServer");
    
    std::cout << "SERVER START..." << std::endl;
    server.start();
    loop.loop();
    
    delete g_logger;
    return 0;
}

5.2 使用流程

复制代码
+--------------------------------------------------+
|                服务器使用流程                      |
+--------------------------------------------------+
|                                                   |
|  1. 初始化日志系统                                 |
|     g_logger = new Logger();                      |
|     g_logger->SetLogLevel(kInfo);                 |
|                                                   |
|  2. 创建事件循环                                   |
|     EventLoop loop;                               |
|                                                   |
|  3. 创建服务器                                     |
|     TcpServer server(&loop, addr, "name");        |
|                                                   |
|  4. 设置回调                                       |
|     server.setConnectionCallback(...);            |
|     server.setMessageCallback(...);               |
|                                                   |
|  5. 设置线程数                                     |
|     server.setThreadNum(4);                       |
|                                                   |
|  6. 启动服务器                                     |
|     server.start();                               |
|                                                   |
|  7. 运行事件循环                                   |
|     loop.loop();                                  |
|                                                   |
+--------------------------------------------------+

六、API 接口

6.1 TcpServer API

6.1.1 构造函数
cpp 复制代码
TcpServer(EventLoop* loop,
          const InetAddress& listenAddr,
          const std::string& nameArg,
          Option option = kNoReusePort);

参数说明

参数 类型 说明
loop EventLoop* 主事件循环
listenAddr const InetAddress& 监听地址
nameArg const std::string& 服务器名称
option Option 端口重用选项

示例

cpp 复制代码
EventLoop loop;
InetAddress addr(8080, "0.0.0.0");
TcpServer server(&loop, addr, "MyServer");
6.1.2 设置回调
cpp 复制代码
void setConnectionCallback(const ConnectionCallback& cb);
void setMessageCallback(const MessageCallback& cb);
void setWriteCompleteCallback(const WriteCompleteCallback& cb);
void setThreadInitCallback(const ThreadInitCallback& cb);

回调类型定义

cpp 复制代码
typedef std::function<void (const TcpConnectionPtr&)> ConnectionCallback;
typedef std::function<void (const TcpConnectionPtr&, Buffer*, Timestamp)> MessageCallback;
typedef std::function<void (const TcpConnectionPtr&)> WriteCompleteCallback;
typedef std::function<void(EventLoop*)> ThreadInitCallback;
6.1.3 启动服务器
cpp 复制代码
void setThreadNum(int numThreads);  // 设置线程数
void start();                        // 启动服务器

6.2 TcpConnection API

6.2.1 基本信息
cpp 复制代码
EventLoop* getLoop() const;
const std::string& name() const;
const InetAddress& localAddress() const;
const InetAddress& peerAddress() const;
bool connected() const;
6.2.2 数据发送
cpp 复制代码
void send(const std::string &buf);
void sendFile(int fileDescriptor, off_t offset, size_t count);
void shutdown();

参数说明

方法 说明
send 发送字符串数据
sendFile 零拷贝发送文件
shutdown 半关闭连接
6.2.3 回调设置
cpp 复制代码
void setConnectionCallback(const ConnectionCallback &cb);
void setMessageCallback(const MessageCallback &cb);
void setWriteCompleteCallback(const WriteCompleteCallback &cb);
void setCloseCallback(const CloseCallback &cb);
void setHighWaterMarkCallback(const HighWaterMarkCallback &cb, size_t highWaterMark);

6.3 EventLoop API

6.3.1 事件循环控制
cpp 复制代码
void loop();  // 启动事件循环
void quit();  // 退出事件循环
6.3.2 任务调度
cpp 复制代码
void runInLoop(Functor cb);   // 在事件循环中执行
void queueInLoop(Functor cb); // 加入任务队列
6.3.3 Channel 管理
cpp 复制代码
void updateChannel(Channel* channel);
void removeChannel(Channel* channel);
bool hasChannel(Channel* channel);

6.4 Buffer API

6.4.1 数据读取
cpp 复制代码
size_t readableBytes() const;
const char *peek() const;
void retrieve(size_t len);
void retrieveAll();
std::string retrieveAllAsString();
std::string retrieveAsString(size_t len);
6.4.2 数据写入
cpp 复制代码
size_t writableBytes() const;
char *beginWrite();
void append(const char *data, size_t len);
6.4.3 I/O 操作
cpp 复制代码
ssize_t readFd(int fd, int *saveErrno);
ssize_t writeFd(int fd, int *saveErrno);

6.5 InetAddress API

cpp 复制代码
explicit InetAddress(uint16_t port = 0, std::string ip = "127.0.0.1");
std::string toIp() const;
std::string toIpPort() const;
uint16_t toPort() const;
const sockaddr_in *getSockAddr() const;

七、外部系统集成指南

7.1 HTTP 服务器集成

cpp 复制代码
#include "TcpServer.h"
#include "EventLoop.h"

class HttpServer {
public:
    HttpServer(EventLoop* loop, const InetAddress& addr)
        : server_(loop, addr, "HttpServer") {
        server_.setMessageCallback(
            std::bind(&HttpServer::onRequest, this, 
                      std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }

private:
    void onRequest(const TcpConnectionPtr& conn, Buffer* buf, Timestamp) {
        // 解析 HTTP 请求
        std::string request = buf->retrieveAllAsString();
        
        // 生成 HTTP 响应
        std::string response = "HTTP/1.1 200 OK\r\n"
                               "Content-Type: text/html\r\n"
                               "Content-Length: 13\r\n"
                               "\r\n"
                               "Hello, World!";
        conn->send(response);
        conn->shutdown();
    }

    TcpServer server_;
};

7.2 RPC 框架集成

cpp 复制代码
class RpcServer {
public:
    RpcServer(EventLoop* loop, const InetAddress& addr)
        : server_(loop, addr, "RpcServer") {
        server_.setMessageCallback(
            std::bind(&RpcServer::onMessage, this, 
                      std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }

private:
    void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp) {
        // 解析 RPC 请求
        while (buf->readableBytes() >= 4) {
            int32_t len = ntohl(*reinterpret_cast<const int32_t*>(buf->peek()));
            if (buf->readableBytes() < 4 + len) break;
            
            buf->retrieve(4);
            std::string request(buf->peek(), len);
            buf->retrieve(len);
            
            // 处理 RPC 调用
            std::string response = processRpc(request);
            
            // 发送响应
            int32_t respLen = htonl(response.size());
            conn->send(std::string(reinterpret_cast<char*>(&respLen), 4) + response);
        }
    }

    std::string processRpc(const std::string& request) {
        // RPC 处理逻辑
        return "result";
    }

    TcpServer server_;
};

7.3 消息队列集成

cpp 复制代码
class MessageQueueBridge {
public:
    MessageQueueBridge(TcpServer* server) : server_(server) {
        server_->setMessageCallback(
            std::bind(&MessageQueueBridge::onMessage, this, 
                      std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
    }

private:
    void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp) {
        std::string msg = buf->retrieveAllAsString();
        // 推送到消息队列
        mq_.push(msg);
    }

    void processFromQueue() {
        while (!mq_.empty()) {
            std::string msg = mq_.pop();
            // 处理消息
        }
    }

    TcpServer* server_;
    MessageQueue mq_;
};

相关推荐
闻缺陷则喜何志丹1 小时前
微分中值定理与导数的应用
c++·高等数学·微分·中值定理·导数应用
tankeven1 小时前
HJ94 记票统计
c++·算法
mjhcsp2 小时前
C++ 树形 DP解析
开发语言·c++·动态规划·代理模式
犽戾武2 小时前
RK3588 上 ROS2 Humble + 串口机械臂驱动(ROS2安装流程 + V1版本Serial驱动)
c++
dgaf2 小时前
DX12 快速教程(15) —— 多实例渲染
c++·microsoft·图形渲染·visual studio·d3d12
mjhcsp2 小时前
C++Z 函数超详细解析
c++·算法·z 函数
小程故事多_802 小时前
深度解析个人AI助手OpenClaw:从消息处理到定时任务的全流程架构
人工智能·架构
青山是哪个青山2 小时前
C++高阶机制与通用技能
c++
白太岁2 小时前
Muduo:(1) 文件描述符及其事件与回调的封装 (Channel)
c++