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

如何使用Boost正确重连TCP socket并保持服务持续监听运行

解决方案

崩溃根因

  • Boost.Beast的WebSocket操作在连接断开、读写异常时会抛出boost::wrapexcept<boost::system::system_error>类型异常,未捕获的异常会直接触发程序终止。
  • 你当前贴出的代码仅实现了TCP端口监听逻辑,实际触发报错的是你完整代码中未贴出的WebSocket握手、数据收发逻辑。

改造实现

你需要为每个客户端连接单独分配线程处理,同时为所有WebSocket操作加异常捕获,避免单个客户端异常导致整个服务崩溃,改造后的参考代码如下:

#include <boost/beast/core.hpp>
#include <boost/beast/websocket.hpp>
#include <iostream>
#include <string>
#include <thread>

using tcp = boost::asio::ip::tcp;
namespace websocket = boost::beast::websocket;

// 单个客户端连接的业务处理逻辑
void handle_client(tcp::socket socket) {
    try {
        // 初始化WebSocket流
        websocket::stream<tcp::socket> ws(std::move(socket));
        // 接受WebSocket握手
        ws.set_option(websocket::stream_base::timeout::suggested(boost::beast::role_type::server));
        ws.accept();
        std::cout << "客户端WebSocket连接建立成功" << std::endl;

        // 循环读写数据
        boost::beast::flat_buffer buffer;
        while (true) {
            // 读取客户端数据
            ws.read(buffer);
            // 原样回写数据(可替换为你的业务逻辑)
            ws.write(buffer.data());
            buffer.consume(buffer.size());
        }
    } catch (const boost::system::system_error& e) {
        // 捕获连接断开异常,仅打印日志不终止程序
        if (e.code() == websocket::error::closed) {
            std::cout << "客户端已正常断开连接" << std::endl;
        } else {
            std::cout << "连接异常:" << e.what() << std::endl;
        }
    } catch (const std::exception& e) {
        std::cout << "业务处理异常:" << e.what() << std::endl;
    }
    // 线程执行结束自动释放连接资源
}

int main() {
    try {
        auto const address = boost::asio::ip::make_address("127.0.0.1");
        auto const port = static_cast<unsigned short>(std::atoi("8080"));

        boost::asio::io_context ioc{1};
        tcp::acceptor acceptor{ioc, {address, port}};
        std::cout << "服务端启动成功,监听端口:" << port << std::endl;

        while (true) {
            tcp::socket socket{ioc};
            // 阻塞等待新客户端连接
            acceptor.accept(socket);
            std::cout << "新TCP连接接入" << std::endl;
            // 启动独立线程处理该客户端逻辑,不阻塞主线程监听
            std::thread(handle_client, std::move(socket)).detach();
        }
    } catch (const std::exception& e) {
        std::cout << "服务端核心异常:" << e.what() << std::endl;
        return 1;
    }
}

可选:固定IP客户端自动重连逻辑

如果你需要的是作为客户端主动连接指定服务端,断开后自动重连,只需要在客户端逻辑外层加循环即可:

void client_reconnect_logic() {
    auto const address = boost::asio::ip::make_address("127.0.0.1");
    auto const port = static_cast<unsigned short>(std::atoi("8080"));
    while (true) {
        try {
            boost::asio::io_context ioc;
            tcp::socket socket(ioc);
            tcp::resolver resolver(ioc);
            boost::asio::connect(socket, resolver.resolve(address, std::to_string(port)));

            websocket::stream<tcp::socket> ws(std::move(socket));
            ws.handshake("127.0.0.1", "/");
            // 后续业务逻辑...
        } catch (const std::exception& e) {
            std::cout << "连接断开,3秒后尝试重连:" << e.what() << std::endl;
            std::this_thread::sleep_for(std::chrono::seconds(3));
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:54:08