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的握手校验选项(不建议随意关闭严格校验,优先遵循标准)
额外建议
- 避免使用
std::thread::detach():detach后的线程无法被管理,建议使用线程池或std::jthread(C++20及以上)管控线程生命周期 - 增加io_context线程数:若服务需处理大量并发连接,可启动多个线程运行io_context,提升并发处理能力
- 用标准请求测试:测试时使用浏览器原生API
new WebSocket("ws://127.0.0.1:8083")发起标准握手请求,避免用普通HTTP请求测试
内容的提问来源于stack exchange,提问作者moksh_mangal
相关产品推荐
相关产品推荐

