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

使用ASIO实现网络通信时持续返回相同接收数据的原因是什么?

问题根因
  • asio::read_until执行成功后,只会将匹配到分隔符TRAILER的内容写入传入的缓冲区对象,不会自动清空/消费已经读取完成的有效数据
  • 你直接调用buffer.data()获取的永远是缓冲区的起始地址,只要你没有删除已处理的旧数据,后续每次读取拿到的都是第一条消息的内容
  • 额外说明:asio::read_until可能预读取超过当前报文的更多数据到缓冲区中,缓存多条后续报文,属于ASIO的正常优化行为,不是Bug
修复方案

你需要先获取本次读取到的有效字节长度,处理完成后主动消费掉已处理的缓冲区数据,修正后的代码如下:

// read_until返回值为本次读取到的有效字节数(包含结尾的TRAILER)
std::size_t read_bytes = asio::read_until(socket, buffer, TRAILER);
// 按实际读取长度构造字符串,避免读取到未初始化内容或者残留旧数据
str_data = std::string(asio::buffer_cast<const char*>(buffer.data()), read_bytes);
// 消费掉已处理的字节,清空缓冲区中这部分旧数据
buffer.consume(read_bytes);
额外注意点
  • 不要直接用std::string(asio::buffer_cast<const char*>(buffer.data()))构造字符串,该写法依赖字符串结尾的\0,网络报文中不一定携带,会导致读取到脏数据或者内存越界
  • 如果TRAILER是自定义分隔符,需要确认服务端发送的每条报文末尾都正确携带该分隔符,否则read_until会一直阻塞直到超时或者缓冲区满

内容的提问来源于stack exchange,提问作者K-D-G

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 16:15:05