简介
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);