Boost logo

Boost Users :

Subject: Re: [Boost-users] [ASIO] Streambuf not containing full line
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2014-02-27 01:23:37


On 27/02/2014 08:55, Quoth Gonzalo Garramuno:
> I am using asio asynchronically. I have:
>
> void tcp_session::start_read()
> {
> // Set a deadline for the read operation.
>
> // input_deadline_.expires_from_now(boost::posix_time::seconds(30));
> // input_deadline_.expires_at(boost::posix_time::pos_infin);
>
> // Start an asynchronous operation to read a newline-delimited message.
> boost::asio::async_read_until(socket(), input_buffer_, '\n',
> boost::bind(&tcp_session::handle_read,
> shared_from_this(),
> boost::asio::placeholders::error));
> }

Are you using the same (unmodified) buffer each time?

async_read_until will pull more than a single line of data into the
given buffer and expects the remaining data to remain in there for the
next call.

> std::string msg;
> std::istream is(&input_buffer_);
> is.exceptions( std::ifstream::failbit | std::ifstream::badbit |
> std::ifstream::eofbit );
>
> try {
> while ( std::getline(is, msg) )

This is the wrong way to do it. This will eat more than the one line
"officially" returned from the read call, including the
still-being-received data at the end.

It's also a waste of time to call "getline" again because you're just
going to make it search for a newline that has already been found by
async_read_until.

A better way to do it is to include
boost::asio::placeholders::bytes_transferred in your handler callback
(as the "size" parameter), which then lets you simply:

     std::string line(boost::asio::buffer_cast<const char
*>(input_buffer_.data()), size);
     input_buffer_.consume(size);

(I believe this leaves the delimiter at the end though, so you might
want to trim that off from your line too; but don't forget to still
consume it.)

Don't call it in a loop; just do it once and then issue the
async_read_until again. This will complete immediately if the buffer
already contains another line.

A bit more complexity is required if you are mixing both async_read and
async_read_until calls on the same socket.


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