Boost.Asio async_send_some无ConstBufferSequence游标及缓冲区推进工具咨询
为什么async_write_some不为ConstBufferSequence提供内置游标功能
- 设计定位原因:async_write_some的核心设计目标是单次尽可能发送最多数据,仅保证单次调用的发送逻辑,上层的发送进度管理属于业务侧的自定义逻辑,不在该接口的设计范围内,故意留出让开发者自主控制的空间。
- 泛用性约束:ConstBufferSequence是Asio定义的轻量概念,所有满足「可迭代、元素为const_buffer类型」的类型都可以作为入参(包括std::array、自定义不可变序列、甚至单个const_buffer实例)。如果内置游标功能,就需要强制要求序列支持修改、裁剪等可变操作,反而会大幅限制接口的泛用性,违背了缓冲区概念的设计初衷。
Asio原生的缓冲区序列推进工具
你猜测的不对,Asio自1.66版本开始就提供了原生的缓冲区序列推进工具,就是boost::asio::buffers_advance,它原生支持所有满足ConstBufferSequence/MutableBufferSequence概念的类型,不需要自己实现推进逻辑。
你代码里的advance逻辑可以直接替换为原生调用,修改后的示例如下:
class koebenhavn : public std::enable_shared_from_this<koebenhavn> { private: boost::asio::ip::tcp::socket socket; public: // ... 省略其他构造、初始化逻辑 void writing(std::vector<const_buffer> buffers, boost::asio::io_context::strand & strand){ // 注意这里把buffers改成值传递避免引用悬空,每次传递的都是当前待发送的分片 socket.async_write_some(buffers, boost::asio::bind_executor(strand, [self=shared_from_this(), buffers, &strand](boost::system::error_code error, size_t transferred) mutable { self->wrote(std::move(buffers), strand, error, transferred); })); } void wrote(std::vector<const_buffer> buffers, boost::asio::io_context::strand & strand, boost::system::error_code error, size_t transferred){ if(!error){ if(transferred > 0){ // 直接用原生接口推进缓冲区 boost::asio::buffers_advance(buffers, transferred); // 如果还有剩余数据就继续发送 if(boost::asio::buffer_size(buffers) > 0){ writing(std::move(buffers), strand); } } } // ... 省略错误处理、完成回调逻辑 } // ... };
注意:如果你的Asio版本低于1.66,也可以用
boost::asio::detail::buffer_sequence_adapter来实现相同逻辑,但绝大多数现有的Boost发行版都已经包含buffers_advance接口,可以直接使用。
内容的提问来源于stack exchange,提问作者Y.Z
相关产品推荐
相关产品推荐

