如何"消费"streambuf并将其转换为const_buffer?
消费streambuf并转换为const_buffer/mutable_buffer的方法
首先要明确:boost::asio::streambuf的内部数据可能由多个非连续内存块组成,且你示例里的receive_buffer是局部变量,直接返回基于它的buffer会导致悬空引用(函数结束后streambuf被销毁,缓冲区失效),必须先把数据持久化处理。
方法1:复制到连续内存(推荐,规避生命周期问题)
把streambuf的数据复制到std::vector<char>或std::string这类连续容器中,再基于容器创建const_buffer:
#include <boost/asio.hpp> #include <vector> #include <iostream> #include <iterator> using boost::asio::ip::tcp; using boost::asio::const_buffer; using boost::asio::streambuf; const_buffer read(boost::shared_ptr<tcp::socket> sock) { boost::system::error_code error; streambuf receive_buffer; boost::asio::read(*sock, receive_buffer, boost::asio::transfer_all(), error); if( error && error != boost::asio::error::eof ) { std::cout << "receive failed: " << error.message() << std::endl; exit(1); } // 将streambuf数据复制到vector,用动态分配保证数据不随函数结束销毁 std::vector<char>* buf_data = new std::vector<char>(); std::istream is(&receive_buffer); buf_data->assign(std::istreambuf_iterator<char>(is), std::istreambuf_iterator<char>()); // 基于vector创建const_buffer return const_buffer(buf_data->data(), buf_data->size()); }
如果用std::string实现:
std::string* buf_str = new std::string(); std::istream is(&receive_buffer); *buf_str << is.rdbuf(); // 读取全部数据 return const_buffer(buf_str->data(), buf_str->size());
实际使用中建议用智能指针管理动态分配的容器,避免内存泄漏。
方法2:直接获取streambuf的缓冲区序列(需保证streambuf生命周期)
如果能确保receive_buffer的生命周期长于返回的buffer(比如将streambuf改为类成员或动态分配),可以直接用streambuf::data()获取缓冲区序列,再通过boost::asio::buffer()转换:
// 此时receive_buffer不能是局部变量 boost::asio::const_buffers_1 buffers = boost::asio::buffer(receive_buffer.data());
这种方式返回的是const_buffer的序列(const_buffers_1是buffer范围),如果需要单个连续buffer,还是优先用方法1。
转换为mutable_buffer的情况
逻辑和const_buffer一致,把数据放到可修改的容器(如vector<char>)后,用mutable_buffer(data->data(), data->size())创建即可。
内容的提问来源于stack exchange,提问作者ring0
相关产品推荐
相关产品推荐

