Beast库中ws.handshake触发未初始化异常,求排查原因
问题排查与修复方案
核心问题1:未完成SSL/TLS握手
你使用的是加密WebSocket(wss://),TCP连接建立后必须先完成SSL层的客户端握手,再执行WebSocket握手。原代码跳过了这一步,导致SSL流未初始化,直接触发未初始化异常。
核心问题2:WebSocket握手参数错误
ws.handshake的第一个参数要求传入主机名或IP地址,而非完整URL。原代码拼接了带端口的完整URL,会导致HTTP请求头中的Host字段格式错误,进一步引发握手失败。
修复后的关键代码片段
// 建立TCP连接后,新增SSL客户端握手步骤 ws.next_layer().handshake(ssl::stream_base::client); // WebSocket握手时,直接传入主机名/IP,而非完整URL ROS_INFO("before handshake"); ws.handshake(ip_addr, "/"); ROS_INFO("after handshake");
额外优化点
- 删除冗余的
url += ":443"代码,wss协议默认端口为443,且握手不需要完整URL - 代码中定义的
cert变量未实际使用,可删除或替换为ctx.add_certificate_authority加载内存中的证书(若无需依赖本地证书文件)
完整修复后的关键流程代码
// ... 保留ctx初始化、resolver解析、TCP连接等原有代码 ... auto ep = beast::get_lowest_layer(ws).connect(results); // 新增:执行SSL客户端握手 ws.next_layer().handshake(ssl::stream_base::client); // 保留User-Agent装饰器代码不变 // 输出主机名而非完整URL std::cout << "Host: " << ip_addr << std::endl; ROS_INFO("before handshake"); ws.handshake(ip_addr, "/"); ROS_INFO("after handshake"); // ... 保留后续write、read、close等代码不变 ...
内容的提问来源于stack exchange,提问作者Karl Miller
相关产品推荐
相关产品推荐

