在用boost的asio开发网络应用时可能会用到2个异步发送函数
(1)basic_stream_socket类的async_write_some函数
这个函数以异步的方式将缓冲区中的数据写入到stream socket中,但是写入
操作不能保证将所有的字节全部写入。
(2)async_write函数
async_write是位于asio命名空间下的一个函数,可以保证将缓冲区中的数据全部
写入到stream socket中。
那么async_write是怎么实现全部写入控制的呢?
以下是async_write一个实现中的源码调用
detail::make_write_op(
s, buffers, transfer_all(), BOOST_ASIO_MOVE_CAST(WriteHandler)(handler))(
boost::system::error_code(), 0, 1);
函数make_write_op会返回一个write_op类的实例,而write_op是一个函数对象,通过这个
函数对象将操作转到operator()中。下面是一个operator实现
void operator()(const boost::system::error_code& ec,
std::size_t bytes_transferred, int start = 0)
{
std::size_t n = 0;
switch (start)
{
case 1:
n = this->check_for_completion(ec, total_transferred_);
for (;;)
{
stream_.async_write_some(//在内部调用async_write_some实现数据的写入
boost::asio::buffer(buffer_ + total_transferred_, n),
BOOST_ASIO_MOVE_CAST(write_op)(*this));//BOOST_ASIO_MOVE_CAST(write_op)(*this)关键点,回掉时使用
return; default:
total_transferred_ += bytes_transferred;
if ((!ec && bytes_transferred == 0)
|| (n = this->check_for_completion(ec, total_transferred_)) == 0
|| total_transferred_ == boost::asio::buffer_size(buffer_))
break;
}
handler_(ec, static_cast<const std::size_t&>(total_transferred_));
}
}
在这个函数中通过async_write_some将数据写入到stream socket中,并在这个函数中
将函数对象自己传递过去,一旦async_write_some操作完成将会调用这时传入的函数对象
在次回掉到这个函数中来,直到全部数据发送完成,调用handler_通知客户程序。