我已经在这方面工作了很长时间,但没有成功。
想象一下,您的主要功能是这样的:
bool running = true;
int i = 0;
//waitHandler();
while(running)
i++;
现在我想添加并调用一个计时器,它将运行设置为假,当它到期时。
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;
}
当然这不起作用(当你取消注释上面的评论时),因为计时器会阻塞主线程。如果我想在不阻塞主要功能的情况下拥有此功能,该怎么办。
编辑:
//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;
}
}
}
如前所述,这几乎显示了预期的行为,但有一些问题:
- 为什么即使使用
run_one
,计时器的处理程序和接收的处理程序都可以被触发 - 当接收到 0 个字节时,为什么接收也会触发。对我来说,这听起来像是没有收到任何东西,并且该功能应该等待?
- 这是正确的方法吗?正如我所说的,我想接收或超时。(像ping)
实际上,当它们出现在 Wireshark 中时,它们的接收顺序是错误的——我猜它与 Wireshark 有关async_receive
,它并没有真正等待传入的消息,而只是在函数调用之前获取缓冲区中的内容。
该怎么办?