I’m trying to implement a timeout for a Boost.Asio read on a TCP socket.
I am trying to use a async_read_some with a deadline_timer. My function below is a member of a class that holds a smart pointer to the TCP socket and io_service. What I would expect to happen when called on an active socket that doesn’t return any data is wait 2 seconds and return false.
What happens is: If the socket never returns any data it works as expected. How ever if the server returns the data the proceeding calls to the method below return immediately because to timers callback is called without waiting the two seconds.
I tried commenting out the async_read_some call and the function always works as expected. Why would async_read_some change how the timer works?
client::client() {
// Init socket and timer
pSock = boost::shared_ptr<tcp::socket > (new tcp::socket(io_service));
}
bool client::getData() {
// Reset io_service
io_service.reset();
// Init read timer
boost::asio::deadline_timer timer(pSock->io_service());
timer.expires_from_now(boost::posix_time::seconds(2));
timer.async_wait(boost::bind(&client::read_timeout, this, boost::system::error_code(), true));
// // Async read the data
pSock->async_read_some(boost::asio::buffer(buffer_),
boost::bind(&client::read_complete,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred
));
// While io_service runs check read result
while (pSock->io_service().run_one()) {
if (m_read_result > 0) {
// Read success
return m_read_result;
}else if(m_read_result < 0){
return false;
}
}
}
}
void client::read_complete(const boost::system::error_code& error, size_t bytes_transferred) {
if (!error) {
m_read_result = bytes_transferred;
}else{
m_read_result = -1;
}
}
void client::read_timeout(const boost::system::error_code& error, bool timeout) {
if(!error){
m_read_result = -1;
}
}
Simple problem when setting up the timer boost::system::error_code() should be changed to _1 or a error::placeholder