You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于boost 1.75.0实现同时监听双端口的boost::asio服务器?

双端口监听的代码调整方案

核心疑问解答

首先明确:你不需要为了双端口监听,在Server类中持有多份socket对象。现有代码里用来做accept中转的成员socket_本身设计上就存在可优化的点,实现多端口监听的核心逻辑是为每一个需要监听的端口,创建独立的、对应绑定端口的acceptor实例,各自跑独立的异步accept循环。

第一步:重构原有Server类

去掉作为accept中转的成员socket,利用Boost.Asio 1.75.0支持的async_accept重载,直接在回调中返回新连接的独立socket,避免成员socket被move后出现状态残留问题:

#include <boost/asio/io_context.hpp>
#include <boost/asio/ip/tcp.hpp>
#include <iostream>
#include "Session.h"

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

class Server
{
public:
    Server(boost::asio::io_context& io_context, const boost::asio::ip::address& listen_addr, short port)
        : acceptor_(io_context, tcp::endpoint(listen_addr, port))
    {
        do_accept();
        std::cout << "Listening on " << acceptor_.local_endpoint() << "\n";
    }

private:
    void do_accept()
    {
        // 异步accept直接返回新连接的socket,不需要提前用成员socket中转
        acceptor_.async_accept(
            [this](boost::system::error_code ec, tcp::socket peer_socket) {
                if (!ec) {
                    std::cout << "Accepted connection from " << peer_socket.remote_endpoint() << "\n";
                    // 直接将新连接的socket移动给Session管理
                    std::make_shared<Session>(std::move(peer_socket))->start();
                }
                // 无论本次accept成功或失败,都继续挂下一个accept任务
                do_accept();
            });
    }

    // 每个Server实例仅持有对应自己监听端口的acceptor即可
    tcp::acceptor acceptor_;
};

重构后的Server类,单实例就对应一个端口的监听能力,不再依赖成员socket_做中转,彻底消除了move后socket状态不一致的隐患。

第二步:初始化双端口的Server实例

所有监听实例共用同一个全局io_context,在主函数里分别创建对应两个端口的Server对象即可:

int main()
{
    boost::asio::io_context io_context;

    // 监听127.0.0.1的6500端口
    Server server_6500(io_context, boost::asio::ip::make_address("127.0.0.1"), 6500);
    // 监听127.0.0.1的6600端口
    Server server_6600(io_context, boost::asio::ip::make_address("127.0.0.1"), 6600);

    // 启动全局事件循环,调度所有异步任务
    io_context.run();
    return 0;
}

补充说明

  • 现有Session类的构造函数存在语法小问题:初始化列表末尾多了一个逗号,编译时会触发告警或错误,记得删除。
  • 如果后续需要扩展监听更多端口,只需要在主函数里新增对应参数的Server实例即可,不需要修改Server类的内部逻辑。
  • 所有的连接、定时器、accept任务都共用同一个io_context,不需要为每个端口单独开事件循环,整体资源开销非常低。

内容的提问来源于stack exchange,提问作者yaodav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 08:24:02