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

WebSocket握手Connection字段缺失upgrade令牌问题求助

解决Boost.Beast WebSocket服务端握手错误:Connection字段缺少upgrade令牌

问题原因

你遇到的The WebSocket handshake Connection field is missing the upgrade token错误,是因为Boost.Beast的WebSocket握手逻辑会严格校验客户端请求的合规性:当客户端发送的握手请求未在Connection头字段中携带upgrade令牌时,ws.accept()会直接抛出异常。这种情况通常发生在:

  • 客户端发送的不是标准WebSocket握手请求(比如误发普通HTTP请求)
  • 客户端的握手请求格式不符合RFC 6455规范

另外原代码未对握手过程的异常做捕获处理,导致错误直接暴露且线程异常终止。

修复后的代码

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

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

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

    boost::asio::io_context ioc{1};
    tcp::acceptor acceptor{ioc, {address, port}};

    while(true){
        try{
            tcp::socket socket{ioc};
            acceptor.accept(socket);
            std::cout << "socket accepted" << std::endl; 

            std::thread{[q = std::move(socket)]() mutable {
                try{
                    boost::beast::websocket::stream<tcp::socket> ws {std::move(q)};
                    
                    // 可选:自定义响应头(兼容老旧客户端时可调整握手选项)
                    // ws.set_option(boost::beast::websocket::stream_base::decorator(
                    //     [](boost::beast::websocket::response_type& res) {
                    //         res.set(boost::beast::http::field::server,
                    //             std::string(BOOST_BEAST_VERSION_STRING) + " websocket-server");
                    //     }));

                    ws.accept();
                    std::cout << "WebSocket handshake succeeded" << std::endl;

                    while(true){
                        boost::beast::flat_buffer buffer;
                        ws.read(buffer);
                        auto out = boost::beast::buffers_to_string(buffer.cdata());
                        std::cout << "Received: " << out << std::endl;
                    }
                } catch(const std::exception& e){
                    std::cerr << "WebSocket connection error: " << e.what() << std::endl;
                }
            }}.detach();
        } catch(const std::exception& e){
            std::cerr << "Accept error: " << e.what() << std::endl;
        }
    }

    return 0;
}

关键改动说明

  • 双层异常捕获:分别处理连接接受阶段、WebSocket握手与通信阶段的错误,避免单个连接的异常导致整个服务崩溃
  • 完善日志输出:明确区分连接状态、握手结果与错误信息,便于快速排查问题
  • (可选)握手装饰器:可自定义响应头,若需兼容老旧客户端,可调整WebSocket的握手校验选项(不建议随意关闭严格校验,优先遵循标准)

额外建议

  1. 避免使用std::thread::detach():detach后的线程无法被管理,建议使用线程池或std::jthread(C++20及以上)管控线程生命周期
  2. 增加io_context线程数:若服务需处理大量并发连接,可启动多个线程运行io_context,提升并发处理能力
  3. 用标准请求测试:测试时使用浏览器原生APInew WebSocket("ws://127.0.0.1:8083")发起标准握手请求,避免用普通HTTP请求测试

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 15:56:03