I'm using asio::async_read_until
with '\n'
delimiter to support a TCP client that fetches character data from a server.
This server continuously sends '\n'
terminated lines; precisely, it can write at once either single lines or a concatenated string of multiple lines.
From the doc, I understand that asio::async_read_until
could read:
'\n'
terminated line, like "some_data\n"
. This is the simplest case, handled with a call the std::getline
on the stream associated with the asio::streambuf
'\n'
terminated line plus the beginning of a next line, like "some_data1\nbla"
. This can be handled with a std::getline
; the rest of the second line will be handled at the next completion handler call.'\n'
. How can I know how many std::getline
calls I should do, knowing that I don't want to risk calling std::getline
on an incomplete line (which I will eventually get in a future packet)? Should I peek at the stream buffer to check the existence of multiple '\n'
? Is it even possible without doing many copies?from the documentation here:
http://www.boost.org/doc/libs/1_59_0/doc/html/boost_asio/reference/async_read_until/overload1.html
If the stream buffer already contains a newline, the handler will be invoked without an async_read_some
operation being executed on the stream.
For this reason, when your handler executes you must execute no more than one getline()
. Once getline
has returned and you have finished processing, simply call async_read_until
again from the handler.
example:
void handler(const boost::system::error_code& e, std::size_t size)
{
if (e)
{
// handle error here
}
else
{
std::istream is(&b);
std::string line;
std::getline(is, line);
do_something(line)
boost::asio::async_read_until(s, b, '\n', handler);
}
}
// Call the async read operation
boost::asio::async_read_until(s, b, '\n', handler);