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

boost::asio中WebSocket相对路径设置及完整URL接入问题

问题解答

一、为什么连接带路径的WebSocket后收不到数据

你当前的代码仅建立了TCP连接,但WebSocket是基于HTTP握手的协议,必须完成规范的握手流程才能和服务器进行数据交互。不带路径时服务器可能默认处理根路径的握手请求,带路径时因为你的请求未包含路径信息,服务器无法识别对应资源,因此不会返回数据。

二、'/rav_path'的正确位置

需要在WebSocket握手的HTTP请求中指定路径,具体是在GET请求行里。TCP连接建立后,你需要向服务器发送如下格式的握手请求:

GET /rav_path HTTP/1.1
Host: 127.0.0.1:82
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

其中第一行的/rav_path就是你要指定的路径。发送后等待服务器返回101 Switching Protocols响应,完成握手后才能进行WebSocket数据的收发。

三、支持完整URL的解决方案:使用Boost.Beast

Boost官方提供的Boost.Beast库,基于Boost.Asio实现了WebSocket的高层封装,支持直接解析完整WebSocket URL,用法和C#的ClientWebSocket类似。

基础示例代码

#include <boost/beast.hpp>
#include <boost/asio.hpp>
#include <iostream>
#include <string>

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

int main() {
    try {
        asio::io_context io_context;
        tcp::resolver resolver(io_context);
        
        // 初始化WebSocket流
        beast::websocket::stream<tcp::socket> ws(io_context);
        // 解析服务器地址
        auto const results = resolver.resolve("127.0.0.1", "82");
        
        // 建立TCP连接
        asio::connect(ws.next_layer(), results.begin(), results.end());
        // 执行WebSocket握手,指定路径/rav_path
        ws.handshake("127.0.0.1", "/rav_path");
        
        // 接收数据示例
        beast::flat_buffer buffer;
        ws.read(buffer);
        std::cout << beast::make_printable(buffer.data()) << std::endl;
        
        // 关闭连接
        ws.close(beast::websocket::close_code::normal);
    } catch (std::exception const& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}

直接解析完整URL的方式

如果想直接传入ws://127.0.0.1:82/rav_path这样的完整URL,可以添加URL解析逻辑:

// 解析完整WebSocket URL
beast::string_view url = "ws://127.0.0.1:82/rav_path";
beast::url parsed_url(url);

asio::io_context io_context;
tcp::resolver resolver(io_context);
beast::websocket::stream<tcp::socket> ws(io_context);

// 解析主机和端口
auto const results = resolver.resolve(parsed_url.host(), parsed_url.port().to_string());
// 建立连接并握手,自动使用URL中的路径
asio::connect(ws.next_layer(), results.begin(), results.end());
ws.handshake(parsed_url.host(), parsed_url.path());

这样就无需手动拆分主机、端口和路径,和C#的用法一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:42:54