网络编程:Boost.Asio实现跨平台的TCP服务器

这正是 Boost.Asio 最擅长的地方!它把 Linux 的 epoll 和 Windows 的 IOCP 封装成了统一的接口,让你完全不用写 #ifdef _WIN32 这种宏来区分平台。

下面我为你展示如何用 C++17 + Boost.Asio 实现一个标准的、跨平台的异步 TCP 服务器。

🛠️ 第一步:环境准备

在写代码之前,你需要确保安装了 Boost 库。

  • Ubuntu/Linux:

    bash 复制代码
    sudo apt-get install libboost-all-dev
  • Windows (使用 vcpkg):

    bash 复制代码
    vcpkg install boost-asio

💻 第二步:核心代码实现

这是一个基于 Reactor 模式 的服务器,支持高并发,且代码在 Windows 和 Linux 上完全通用。

cpp 复制代码
#include <iostream>
#include <vector>
#include <memory>
#include <thread>
#include <boost/asio.hpp>

using boost::asio::ip::tcp;
using namespace std;

// 1. 会话类:负责处理单个客户端的连接
class Session : public enable_shared_from_this<Session> {
    tcp::socket socket_;
    enum { max_length = 1024 };
    char data_[max_length];

public:
    Session(tcp::socket socket) : socket_(std::move(socket)) {}

    void start() {
        do_read();
    }

private:
    void do_read() {
        // 异步读取:不阻塞线程
        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) {
                if (!ec) {
                    // 读取成功,异步回写
                    do_write(length);
                }
            });
    }

    void do_write(std::size_t length) {
        auto self(shared_from_this());
        boost::asio::async_write(
            socket_, boost::asio::buffer(data_, length),
            [this, self](boost::system::error_code ec, std::size_t /*length*/) {
                if (!ec) {
                    // 写完后继续读
                    do_read();
                }
            });
    }
};

// 2. 服务器类:负责监听端口和接受连接
class TcpServer {
    boost::asio::io_context& io_context_;
    tcp::acceptor acceptor_;

public:
    TcpServer(boost::asio::io_context& io_context, short port)
        : io_context_(io_context),
          acceptor_(io_context, tcp::endpoint(tcp::v4(), port))
    {
        do_accept();
    }

private:
    void do_accept() {
        // 异步接受新连接
        acceptor_.async_accept(
            [this](boost::system::error_code ec, tcp::socket socket) {
                if (!ec) {
                    // 创建会话对象并开始处理
                    make_shared<Session>(std::move(socket))->start();
                    cout << "New client connected" << endl;
                }
                // 继续接受下一个连接
                do_accept();
            });
    }
};

int main() {
    try {
        // 1. 创建 io_context (核心事件循环)
        boost::asio::io_context io_context;

        // 2. 启动服务器
        TcpServer server(io_context, 12345);

        cout << "Server running on port 12345..." << endl;

        // 3. 启动多线程池 (模拟多线程处理)
        // 在 Windows 下底层是 IOCP,Linux 下是 epoll
        vector<thread> threads;
        for (int i = 0; i < 4; ++i) {
            threads.emplace_back([&io_context]() {
                io_context.run();
            });
        }

        // 等待所有线程结束
        for (auto& t : threads) {
            t.join();
        }

    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}

📝 第三步:编译与运行

Linux (g++)
bash 复制代码
g++ -std=c++17 server.cpp -o server -lboost_system -pthread
./server
Windows (CMake + vcpkg)

如果你使用 CMake,CMakeLists.txt 非常简单:

cmake 复制代码
cmake_minimum_required(VERSION 3.10)
project(TcpServer)

set(CMAKE_CXX_STANDARD 17)

find_package(Boost REQUIRED COMPONENTS system)

add_executable(server server.cpp)
target_link_libraries(server PRIVATE Boost::system)

🔍 为什么它能跨平台?(核心原理)

Boost.Asio 的魔法在于它封装了底层的差异:

层面 Linux 底层 Windows 底层 Boost.Asio 封装
I/O 多路复用 epoll IOCP (完成端口) boost::asio::io_context
Socket 句柄 int (文件描述符) SOCKET (句柄) boost::asio::ip::tcp::socket
错误码 errno WSAGetLastError() boost::system::error_code
启动/关闭 无特殊操作 WSAStartup / WSACleanup 自动处理 (无需手动调用)

🌟 代码亮点解析

  1. boost::asio::io_context :

    这是整个库的心脏。在 Linux 上,调用 io_context.run() 时,它内部会去 epoll_wait;在 Windows 上,它会去 GetQueuedCompletionStatus (IOCP)。你完全不用关心底层。

  2. enable_shared_from_this :

    在 Session 类中,我们使用了 shared_from_this()。这是为了防止异步操作(如 async_read)还在进行时,Session 对象被意外销毁。这是一种非常安全的内存管理方式。

  3. 多线程模型 :

    代码最后启动了 4 个线程运行 io_context.run()。

    • Linux 下 :这 4 个线程会同时抢锁处理 epoll 返回的就绪事件。
    • Windows 下:这 4 个线程会作为 IOCP 的工作线程池,自动负载均衡。

🚀 总结

使用 Boost.Asio,你只需要关注业务逻辑 (怎么读、怎么写),而不用关心系统调用(怎么监听、怎么轮询)。这就是它成为 C++ 网络编程事实标准的原因。

相关推荐
草莓熊Lotso几秒前
【C++ 基于微服务的即时通讯系统】Elasticsearch 从安装到 C++ 客户端二次封装全落地
linux·网络·数据库·c++·elasticsearch·微服务
海量计划5 分钟前
网络基础
网络
曦夜日长7 分钟前
主从 Reactor 高并发服务器实战 (一):前置知识与功能目标
运维·服务器
云和数据.ChenGuang14 分钟前
AI 工程师相关就业岗位(细分,偏工程落地,由底层到上层)
服务器·开发语言·人工智能·python
LiaoWL12319 分钟前
从零开始学 Linux(二):Shell 脚本入门与文本处理实战
linux·运维·服务器
Nebula_g1 小时前
云禾外卖补充—项目整体后端运行逻辑-对流程的更深层次理解
java·开发语言·网络·数据库·状态模式·javase
djjjx.1 小时前
Linux进程篇(三):深度硬核!全面起底 Linux 进程状态变化与内核链表动态解绑
linux·运维·服务器
乔旭伟1 小时前
Linux 服务器环境搭建实战笔记:最小化安装、Docker Compose 编排与上线检查全流程
linux·服务器·笔记
燕落南枝1 小时前
HTML 学习:input 单选、复选与文件域详解
服务器·学习·html
一次旅行2 小时前
DeepSeek‑V4.1‑Flash‑1017完整解读:模型升级+Search/Fetch搜索API开放,Agent开发者要注意哪些坑
前端·网络·人工智能