Boost logo

Boost Users :

Subject: Re: [Boost-users] [asio] continuous reads into streambuf
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2018-05-24 23:44:00


On 25/05/2018 02:59, Stephan Menzel wrote:
> once again I find myself struggling with asio streambufs but wanted to
> ask here before chicken out to char buffers again.
> My problem is that I cannot read more than one protocol loop successfully.
[...]
>   asio::async_read_until(m_socket, m_streambuf, "\r\n",
[...]
>   asio::async_read(m_socket, m_streambuf,
> boost::asio::transfer_exactly(n_header_size),

Mixing read_until and read on the same socket is problematic, because
the way they actually behave -- while not actually wrong -- is not what
you first expect.

There are two key bits of information you need to realise the problem:

  1. async_read_until actually calls async_read_some under the hood to
read an arbitrary amount of data from the socket. All the data is
stored in the streambuf and only a *subset* of that length is returned
to indicate where the terminator was found.

  2. async_read just calls async_read_some directly with the specified
length request.

In particular, even if #1 already read the entire message into the
streambuf, #2 will ignore that and still wait for the specified number
of new incoming bytes -- even if you are reading into the same streambuf.

The solution to this is pretty straightforward, once you realise that
you need to do it:

Instead of calling async_read with the total number of bytes you are
expecting in the message body, first check how many bytes are already
available in the streambuf (via size()), and only issue a read for the
balance (and if the balance is 0 or negative, then obviously don't issue
the read at all).

In an ideal world, async_read would do this for you, but it doesn't.
(And it does make sense that it doesn't, once you think about it --
otherwise multiple consecutive reads without consuming the data would
just return the same data over and over instead of appending it.)


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net