C++ boost::json::stream_parser解析WebSocket flat_buffer报错咨询
报错原因
extra data错误由三个问题直接导致:
parser.write第一个参数传错:该接口要求传入存储JSON文本的连续字符首地址,你直接传入了flat_buffer对象本身,而非缓冲区内部存储的接收数据。你之前用boost::make_printable(buffer.data())能正常打印消息,是因为该工具专门适配了asio的缓冲区结构,能正确取出内部存储的字符,但stream_parser::write没有适配flat_buffer类型,会直接把传入的对象内存块当做字符数组解析,必然出现非法冗余数据。- 长度参数传错:
buffer.size()返回的是flat_buffer当前可读区间的总长度,不是本次WebSocket读取实际拿到的有效字节数,容易将缓冲区的历史残留无效数据计入解析范围。 - 缺失收尾调用:喂完数据后没有调用
finish()告知解析器所有输入已提供,解析器无法完成JSON边界校验。
正确实现代码
beast::websocket::stream<ssl::stream<tcp::socket>> ws; boost::beast::flat_buffer buffer; boost::json::stream_parser parser; // 每次读取前清空缓冲区,避免历史数据残留 buffer.clear(); // 读取完整WebSocket消息,记录实际读取到的有效字节数 std::size_t bytes_read = ws.read(buffer); // 传入缓冲区内部存储的字符首地址、有效数据长度 parser.write(static_cast<const char*>(buffer.data().data()), bytes_read); // 告知解析器所有数据已传入,触发最终边界校验 parser.finish(); assert(parser.done()); boost::json::value jsn = parser.release(); // 解析完成后消费已处理的数据,避免影响下次读取 buffer.consume(bytes_read);
补充说明
boost::beast::flat_buffer本身保证所有可读数据存储在连续内存块中,因此可以直接通过buffer.data().data()拿到JSON文本的起始指针,不需要额外做分块拼接。- 如果后续需要手动处理WebSocket分片读取场景,可以多次调用
parser.write()喂入分批收到的数据,等所有分片接收完成后再调用parser.finish()即可,不需要手动拼接完整字符串。 - 如果修正参数后仍然报
extra data错误,可以先打印传入parser的完整文本,确认收到的WebSocket消息中JSON尾部是否存在自定义分隔符、冗余字节,这类场景需要先截断出合法JSON区间再喂给解析器。
内容的提问来源于stack exchange,提问作者Isaac Martinez Jr. Mora
相关产品推荐
相关产品推荐

