I'm using the Boost ASIO library to write a TCP client program.
The protocol starts with a banner line when you connect followed by '\r\n' I can send commands at any time much like smtp.
However, the server can also send me data when I don't ask for it and it's terminated with a '\r\n'
I have a line like to this to read and parse the initial connection banner Which means, stop reading when I get "\r\n".
boost::asio::streambuf response_;
...
boost::asio::async_read_until(socket_, response_, "\r\n",
boost::bind(&PumpServerClient::HandleReadBanner, this,
boost::asio::placeholders::error));
But at various times I want to be able to ask the question, is there data available? if there is, read it until "\r\n". I feel like I need a peek function but I can't see where that is.
Ok, perhaps I can call async_read_until again. But consider this... it never ends. The keep reading debug appears once. Obvious, it's waiting forever to complete but never does.
void client::HandleReadRequest(const boost::system::error_code& err)
{
if (!err){
// Got some data, print it out
std::ostringstream ss;
ss << &response_;
std::cout << ss.str() << std::endl;
// Keep reading...
boost::asio::async_read_until(socket_, response_, "\r\n",
boost::bind(&client::HandleReadRequest, this, boost::asio::placeholders::error));
std::cout << "keep reading" << std::endl;
}
else
{
std::cout << "Error: " << err.message() << "\n";
}
}
Ok, I think I get it now. I wasn't looking at a full enough example to base my code off.
It looks like calling:
boost::asio::async_read_until(socket_, response_, "\r\n", boost::bind(&client::HandleReadRequest, this, boost::asio::placeholders::error)); means that when a \r\n appears in the response_ buffer, the function HandleReadRequest will be called. I only need to call async_read_until once. unless a write request is called then I need to do a read again... it appears... well I have it working now at least.