关于boost::asio::async_write的实现机制

时间:2022-05-06 20:02:07


在用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_通知客户程序。