Boost.Asio递归调用start后,回调函数为何立即触发?
问题原因与解决方案
你的问题核心是streambuf未正确消费已处理数据,且未判断错误码就递归调用start(),导致回调被无限触发。
具体原因:
async_read_until完成后,读取到的数据会保留在buf中,但你没有调用buf.consume(bytes_transferred)移除已处理的字节。下一次调用start()时,async_read_until会直接检测到缓冲区里已有分隔符"\0",无需等待新的网络数据就立即触发回调,形成无限递归循环。- 未处理
error_code:即使连接断开(如客户端下线),回调仍会执行并继续调用start(),导致无意义的循环。
修正后的代码:
class session : public std::enable_shared_from_this<session> { public: session(tcp::socket&& socket) : socket(std::move(socket)) {} void start() { async_read_until(socket, buf, "\0", [self = shared_from_this()](boost::system::error_code code, size_t bytes_transferred) { // 检测错误,连接异常则终止会话 if (code) { std::cout << "会话异常或关闭: " << code.message() << "\n"; return; } // 提取数据时剔除末尾的"\0"分隔符 std::string require(buffer_cast<const char*>(self->buf.data()), bytes_transferred - 1); std::cout << "GET: " << require << "\n"; if (require == "Hi") { async_write(self->socket, buffer("Hello\0"), [](boost::system::error_code code, size_t) { if (!code) { std::cout << "SEND: Hello\n"; } }); } // 消费已处理的字节,清空缓冲区已用部分 self->buf.consume(bytes_transferred); // 发起下一次异步读取 self->start(); }); } private: tcp::socket socket; boost::asio::streambuf buf; };
内容的提问来源于stack exchange,提问作者Xeim
相关产品推荐
相关产品推荐

