boost创建一个服务端

boost创建一个服务端

1. Reactor 模式

Boost.Asio 基于 Reactor 模式(也称为事件驱动模式):

  • 一个中心 事件循环(io_context)不断检查事件
  • 当事件就绪时(如数据到达、连接请求),调用相应的回调函数
  • 避免为每个连接创建线程,资源利用率高

2. Proactor 模式扩展

Asio 实际上是 Proactor 模式的实现:

  • 应用程序发起异步操作
  • 操作系统执行实际 I/O
  • 操作完成后,Asio 在事件循环中调用完成处理程序

组件工作原理

1. io_context - 事件调度中心

boost::asio::io_context io_context_;

作用:Asio 的核心,负责:

  • 管理所有异步操作
  • 分发 I/O 事件到相应的完成处理程序
  • 提供事件循环机制

工作流程

启动 → 检查就绪事件 → 调用回调 → 再检查 → ...

2. acceptor - 连接接收器

tcp::acceptor acceptor_(io_context, tcp::endpoint(tcp::v4(), port));

工作原理

客户端连接请求 → 操作系统TCP栈 → acceptor检测到 → 调用async_accept回调

3. 异步操作链

连接接受流程:
void do_accept() {
    acceptor_.async_accept([this](error_code ec, tcp::socket socket) {
        if (!ec) {
            std::make_shared<Session>(std::move(socket))->start();
        }
        do_accept();  // ⬅️ 关键:递归调用,持续监听新连接
    });
}
数据读取流程:
void do_read() {
    socket_.async_read_some(
        boost::asio::buffer(data_),
        [this, self](error_code ec, std::size_t length) {
            if (!ec) {
                do_write(length);  // ⬅️ 读取成功后写入
            }
        });
}
数据写入流程:
void do_write(std::size_t length) {
    boost::asio::async_write(
        socket_, 
        boost::asio::buffer(data_, length),
        [this, self](error_code ec, std::size_t /*length*/) {
            if (!ec) {
                do_read();  // ⬅️ 写入成功后继续读取
            }
        });
}

关键机制详解

1. 异步操作链

accept → read → write → read → write → ...
  • 每个异步操作完成时,启动下一个操作
  • 形成永不停歇的处理链条
  • 自动维持连接的生命周期

2. 共享所有权与生命周期管理

class Session : public std::enable_shared_from_this<Session> {
    // 使用 shared_ptr 确保 Session 在异步操作期间保持存活
};

原理

  • 异步操作可能在任何时间完成
  • 使用 shared_ptr 确保回调执行时对象仍然存在
  • enable_shared_from_this 允许在成员函数中获取自身的 shared_ptr

3. 多线程处理模型

// 主线程创建工作者线程
std::vector<std::thread> threads;
for (std::size_t i = 0; i < thread_pool_size_; ++i) {
    threads.emplace_back([this]() {
        io_context_.run();  // ⬅️ 每个线程运行独立的事件循环
    });
}

线程模型

主线程
  │
  ├── 工作者线程1 → io_context.run()
  ├── 工作者线程2 → io_context.run()
  ├── 工作者线程3 → io_context.run()
  └── 工作者线程4 → io_context.run()

关键点

  • 所有线程共享同一个 io_context
  • 操作系统负责将就绪事件分配到空闲线程
  • 内置同步机制,线程安全

4. 信号处理与优雅关闭

boost::asio::signal_set signals_(io_context_);
signals_.add(SIGINT);
signals_.add(SIGTERM);

signals_.async_wait([this](error_code /*ec*/, int /*signo*/) {
    io_context_.stop();  // ⬅️ 停止事件循环
});

关闭流程

  1. 用户按下 Ctrl+C 产生 SIGINT 信号
  2. Asio 捕获信号,调用注册的回调
  3. 回调中调用 io_context.stop()
  4. 所有线程的 run() 方法返回
  5. 程序正常退出

性能优势原理

1. 避免线程爆炸

  • 传统方案:一个连接一个线程
  • Asio 方案:固定线程池 + 异步 I/O
  • 可处理数千个并发连接而不会创建数千个线程

2. 零拷贝优化

socket_.async_read_some(boost::asio::buffer(data_));
  • 数据直接从网卡缓冲区读到应用缓冲区
  • 减少内存拷贝次数

3. 系统调用批处理

  • 多个异步操作在一次系统调用中处理
  • 减少用户态-内核态切换开销

事件循环内部机制

io_context.run() 的工作流程:

while (有未完成的操作 || 有就绪的事件) {
    1. 检查是否有完成的异步操作
    2. 如果有,调用对应的完成处理程序
    3. 如果没有,阻塞等待新事件
    4. 处理新到达的事件
}

这种设计使得 Boost.Asio 服务端能够以极高的效率处理大量并发连接,是现代高性能网络编程的范实现。

std::make_shared(std::move(socket))->start() 这种模式提供了:

安全的所有权转移 - 使用 std::move

自动生命周期管理 - 使用 shared_ptr + enable_shared_from_this

异常安全 - 资源自动释放

高性能 - make_shared 优化内存分配

自然的异步编程模型 - 对象生命周期与异步操作匹配

这是现代 C++ 异步服务器编程中的最佳实践,结合了 RAII、智能指针和移动语义等核心特性。

#include <boost/asio.hpp>
#include <iostream>
#include <memory>
#include <thread>
#include <vector>
#include <string>

using boost::asio::ip::tcp;

class Session : public std::enable_shared_from_this<Session> {
public:
    Session(tcp::socket socket) : socket_(std::move(socket)) {
        std::cout << "Session 构造函数" << std::endl;
    }

    void start() {
        std::cout << "Session::start() 调用" << std::endl;
        try {
            auto endpoint = socket_.remote_endpoint();
            std::cout << "客户端连接: " << endpoint << std::endl;

            // 设置socket选项
            boost::system::error_code opt_ec;
            socket_.set_option(tcp::no_delay(true), opt_ec);
            if (opt_ec) {
                std::cerr << "设置no_delay错误: " << opt_ec.message() << std::endl;
            }

            send_welcome();
        }
        catch (const std::exception& e) {
            std::cerr << "获取客户端端点异常: " << e.what() << std::endl;
            // 即使有异常也尝试发送欢迎消息
            send_welcome();
        }
    }

private:
    void send_welcome() {
        std::cout << "Session::send_welcome() 调用" << std::endl;
        auto self(shared_from_this());

        // 检查socket状态
        boost::system::error_code ec;
        auto endpoint = socket_.remote_endpoint(ec);
        if (ec) {
            std::cerr << "检查socket状态错误: " << ec.message() << std::endl;
            return;
        }

        std::string welcome_msg = "欢迎连接到服务器! 发送任何消息将会回显.\r\n";
        std::cout << "准备发送欢迎消息: " << welcome_msg.length() << " 字节" << std::endl;

        // 使用async_write确保全部数据发送
        boost::asio::async_write(
            socket_,
            boost::asio::buffer(welcome_msg),
            [this, self, welcome_msg](boost::system::error_code ec, std::size_t length) {
                std::cout << "欢迎消息回调执行, ec: " << ec.message()
                    << ", 长度: " << length << std::endl;

                if (!ec) {
                    if (length == welcome_msg.length()) {
                        std::cout << "欢迎消息完整发送" << std::endl;
                    }
                    else {
                        std::cout << "欢迎消息部分发送: " << length << "/" << welcome_msg.length() << std::endl;
                    }
                    do_read();
                }
                else {
                    std::cerr << "发送欢迎消息错误: " << ec.message() << std::endl;
                    // 即使发送失败也继续读取
                    do_read();
                }
            });
    }

    void do_read() {
        std::cout << "Session::do_read() 调用" << std::endl;
        auto self(shared_from_this());

        socket_.async_read_some(
            boost::asio::buffer(data_, max_length),
            [this, self](boost::system::error_code ec, std::size_t length) {
                std::cout << "读取回调执行, ec: " << ec.message()
                    << ", 长度: " << length << std::endl;

                if (!ec && length > 0) {
                    // 确保字符串正确终止
                    if (length < max_length) {
                        data_[length] = '\0';
                    }
                    else {
                        data_[max_length - 1] = '\0';
                        length = max_length - 1;
                    }

                    std::string received_data(data_, length);
                    std::cout << "收到数据: \"" << received_data << "\"" << std::endl;

                    do_write(length);
                }
                else if (ec) {
                    handle_error(ec, "读取");
                }
                else {
                    std::cout << "读取到0字节数据" << std::endl;
                    do_read(); // 继续读取
                }
            });
    }

    void do_write(std::size_t length) {
        auto self(shared_from_this());
        std::string echo_msg = "服务器回显: " + std::string(data_, length) + "\r\n";

        boost::asio::async_write(
            socket_,
            boost::asio::buffer(echo_msg),
            [this, self, echo_msg](boost::system::error_code ec, std::size_t written) {
                std::cout << "回显回调执行, ec: " << ec.message()
                    << ", 写入: " << written << " 字节" << std::endl;

                if (!ec) {
                    std::cout << "回显消息发送成功: \"" << echo_msg << "\"" << std::endl;
                    do_read();
                }
                else {
                    std::cerr << "回显写入错误: " << ec.message() << std::endl;
                }
            });
    }

    void handle_error(boost::system::error_code ec, const std::string& operation) {
        if (ec == boost::asio::error::eof) {
            std::cout << "客户端正常断开连接" << std::endl;
        }
        else if (ec == boost::asio::error::operation_aborted) {
            std::cout << "操作被取消" << std::endl;
        }
        else {
            std::cerr << operation << "错误: " << ec.message() << std::endl;
        }
    }

    tcp::socket socket_;
    enum { max_length = 1024 };
    char data_[max_length];
};


// 服务器类
class Server {
public:
    Server(boost::asio::io_context& io_context, short port)
        : acceptor_(io_context, tcp::endpoint(tcp::v4(), port)) {
        std::cout << "服务器启动,监听端口: " << port << std::endl;
        do_accept();
    }

private:
    void do_accept() {
        acceptor_.async_accept(
            [this](boost::system::error_code ec, tcp::socket socket) {
                if (!ec) {
                    // 创建新会话来处理连接
                    std::make_shared<Session>(std::move(socket))->start();
                }
                else {
                    std::cerr << "接受连接错误: " << ec.message() << std::endl;
                }

                // 继续接受下一个连接
                do_accept();
            });
    }

    tcp::acceptor acceptor_;
};

// 带线程池的服务器
class ThreadPoolServer {
public:
    ThreadPoolServer(short port, std::size_t thread_pool_size = 4)
        : io_context_(),
        signals_(io_context_),
        server_(io_context_, port),
        thread_pool_size_(thread_pool_size) {

        // 注册信号处理,用于优雅关闭
        signals_.add(SIGINT);
        signals_.add(SIGTERM);
        do_await_stop();
    }

    void run() {
        // 创建线程池
        std::vector<std::thread> threads;
        for (std::size_t i = 0; i < thread_pool_size_; ++i) {
            threads.emplace_back([this]() {
                try {
                    std::cout << "线程 " << std::this_thread::get_id() << " 开始运行" << std::endl;
                    io_context_.run();
                    std::cout << "线程 " << std::this_thread::get_id() << " 结束运行" << std::endl;
                }
                catch (const std::exception& e) {
                    std::cerr << "IO上下文运行异常: " << e.what() << std::endl;
                }
                });
        }

        std::cout << "服务器运行中,使用 " << thread_pool_size_ << " 个工作线程" << std::endl;
        std::cout << "按 Ctrl+C 停止服务器" << std::endl;

        // 等待所有线程完成
        for (auto& thread : threads) {
            thread.join();
        }
    }

private:
    void do_await_stop() {
        signals_.async_wait([this](boost::system::error_code /*ec*/, int /*signo*/) {
            std::cout << "\n正在停止服务器..." << std::endl;
            io_context_.stop();
            });
    }

    boost::asio::io_context io_context_;
    boost::asio::signal_set signals_;
    Server server_;
    std::size_t thread_pool_size_;
};

int main(int argc, char* argv[]) {
    try {
        short port = 8080;
        if (argc == 2) {
            port = std::atoi(argv[1]);
        }

        std::cout << "启动 Boost.Asio 服务器..." << std::endl;
        ThreadPoolServer server(port);
        server.run();

        std::cout << "服务器已停止" << std::endl;
    }
    catch (const std::exception& e) {
        std::cerr << "异常: " << e.what() << std::endl;
        return 1;
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值