asio之读写
简介
asio读写支持同步和异步
读操作
主要在read.hpp,read_at.hpp和read_until.hpp文件中
异步读函数对象有
- read_until_delim_op
- read_until_delim_string_op
- read_until_expr_op
- read_until_match_op
- read_streambuf_op
- read_op
- read_at_op
- read_at_streambuf_op
写操作
主要在write.hpp,write_at.hpp文件中
异步写函数对象有
- write_at_op
- write_at_streambuf_op
- write_op
- write_streambuf_handler
异步操作分析
异步操作可能在调用线程和io线程中调用,以read_until_delim_op为例,其第三个参数为默认参数,区分不同线程的调用。在switch语句中,使用循环,同时循环中使用了default分支。
void operator()(const boost::system::error_code& ec,std::size_t bytes_transferred, int start = 0){const std::size_t not_found = (std::numeric_limits<std::size_t>::max)();std::size_t bytes_to_read;switch (start_ = start){case 1:for (;;){{// Determine the range of the data to be searched.typedef typename boost::asio::basic_streambuf<Allocator>::const_buffers_type const_buffers_type;typedef boost::asio::buffers_iterator<const_buffers_type> iterator;const_buffers_type buffers = streambuf_.data();iterator begin = iterator::begin(buffers);iterator start_pos = begin + search_position_;iterator end = iterator::end(buffers);// Look for a match.iterator iter = std::find(start_pos, end, delim_);if (iter != end){// Found a match. We're done.search_position_ = iter - begin + 1;bytes_to_read = 0;}// No match yet. Check if buffer is full.else if (streambuf_.size() == streambuf_.max_size()){search_position_ = not_found;bytes_to_read = 0;}// Need to read some more data.else{// Next search can start with the new data.search_position_ = end - begin;bytes_to_read = read_size_helper(streambuf_, 65536);}}// Check if we're done.if (!start && bytes_to_read == 0)break;// Start a new asynchronous read operation to obtain more data.stream_.async_read_some(streambuf_.prepare(bytes_to_read),BOOST_ASIO_MOVE_CAST(read_until_delim_op)(*this));return; default:streambuf_.commit(bytes_transferred);if (ec || bytes_transferred == 0)break;}const boost::system::error_code result_ec =(search_position_ == not_found)? error::not_found : ec;const std::size_t result_n =(ec || search_position_ == not_found)? 0 : search_position_;handler_(result_ec, result_n);}}
在发起异步调用时直接return了
stream_.async_read_some(streambuf_.prepare(bytes_to_read),BOOST_ASIO_MOVE_CAST(read_until_delim_op)(*this));
return; default:
当在io线程调用时,会进入default分支,如果数据没有读完,会进入for循环,继续发起异步读取返回。直到将数据读取完毕, 才会调用自定义的handler
handler_(result_ec, result_n);