I am already working long on this without success.
Imagine you have your main function some sort like this:
bool running = true;
int i = 0;
//waitHandler();
while(running)
i++;
Now I would like to add and call a timer, which sets running to false, when it expires.
void waitHandler(){
boost::asio::io_service timerService;
//create and bind the timer
boost::asio::deadline_timer timer(timerService,
boost::posix_time::milliseconds(2000));
timer.wait();
running = true;
cout<<"WaitHandler triggered"<<endl;
}
Of course this does not work (when u uncomment the comment above), since the timer will block the main thread. What to do, if I would want to have this functionality without blocking the main function.
EDIT:
//transfer some error message
void set_result(boost::system::error_code* a, boost::system::error_code b,deadline_timer &timer)
{
a->assign(b.value(),b.category());
}
template<class SOCKET>
void read_with_timeout(SOCKET & sock, unsigned int delay,
const asio::mutable_buffers_1& buffers)
{
//create error messages
boost::system::error_code timer_result;
boost::system::error_code read_result;
//initialize timer
deadline_timer timer(sock.get_io_service());
timer.expires_from_now(boost::posix_time::milliseconds(delay));
timer.async_wait(boost::bind(set_result, &timer_result, _1,boost::ref(timer)));
//initialize receive mechanism
sock.async_receive(buffers, boost::bind(set_result, &read_result, _1,boost::ref(timer)));
sock.get_io_service().reset();
//should run for one handler
while (sock.get_io_service().run_one())
{
if (read_result.value()==0){ //zero stands for, that the message was received properly.
timer.cancel();
//cout<<"Message received: => Timer cancelled => RETURN!"<<endl;
return;
}
if(timer.expires_from_now().total_milliseconds() <=0){
sock.cancel();
//cout<<"Timeout => Socket cancelled => RETURN!"<<endl;
return;
}
}
}
As said this almost shows the wished behavior, but there are some questions to it:
- Why by even using
run_one
, both the handler for the timer and the one for the receive can be fired - Why does receive also fire, when 0 bytes are received. For me that sounds like nothing is received and the function is supposed to wait?
- Is this the right way to do it - as I said I want to receive or timeout. (like pinging)
Actually the pakets are received in wrong order as they appeared in Wireshark - I guess it has something to do with async_receive
, which does not really wait for a incoming message, but just takes what is in the buffer before the function call.
What to do?