asio网络通讯库是一个比较底层的库,分为结合boost使用的,和单独使用的,也就是standalone,而在我们使用的过程中会遇到服务端一致等待的情况,这些和我们的业务逻辑有所区别,所以需要对超时进行处理,但是,基于asio的tcp是有这个超时处理函数的wait_read,而udp则没有,刚好项目中遇到了,所以就记录一下解决过程。
问题:我在使用udp写服务端的时候,用receive_from函数来等待读取数据,但是希望在60秒内没有数据的话就跳出这个函数,执行其他操作。
解决办法:通过使用linux系统下的一个alarm函数来实现,具体代码如下。
signal_action.sa_flags = 0;
sigemptyset(&signal_action.sa_mask);
signal_action.sa_handler = SignalHandler;
if(sigaction(SIGALRM,&signal_action,NULL) == -1)
{
// 错误处理
}
int timeout_in_seconds = 60;
alarm(timeout_in_seconds);
socket.receive_from(asio::buffer(recv_buf),remote_endpoint,0,error);
alarm(0);
以上代码就可以完美解决我们遇到的udp超时处理的问题。
下边解释以下这个liunx下的alarm函数
通过查找那个男人(man一下),发现函数的原型是:unsigned int alarm(unsigned int seconds);
参数是秒,也就你想要等待的时间;返回值是剩余的等待时间是多少。
函数描述:设置定时器,在指定的seconds后,内核会给当前进程发送一个SIGALRM信号,进程收到该信号,默认动作终止,每个进程都有且只有唯一的一个定时器。
取消定时器,使用alarm(0),返回值是旧的定时器剩下的秒数。
alarm使用的是自然定时法,和进程的状态无关(无论进程是出于就绪、运行、挂起、阻塞、暂停、终止、甚至是僵尸进程)alarm都计时间,通俗的理解为alarm这定时器优先级高于一切进程。
如果是windows系统下,这个还有另外一种解决方法就是调用windows下的设置定时器的函数,这个在这里不再多说,这里主要是针对linux系统下的处理方式。
项目中的总结,希望能帮助到你!