注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

NET START HERE

研究C/C++、网络/通信/协议编程、网络安全、软件安全

 
 
 

日志

 
 

linux C使用alarm设置套接字接收函数recvfrom超时  

2011-08-20 14:13:28|  分类: 技术探讨 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
一、 使用时钟和定时器(alarm系统调用)
 
#include <unistd.h>
unsigned alarm(unsigned secs);
/*returns secs left on previous alarm or zero if none */
 
alarm也称为闹钟函数,它可以在进程中设置一个定时器,当指定的时间到时,它向进程发送SIGALRM信号。需要注意的是,一个进程只能有一个定时器。当报警开始时,会发送一个SIGALRM,子进程继承其父进程的报警时钟值,但实际的时钟并不共享。执行exec后,报警时钟仍然保持其设置。
alarm按照secs指定的秒数来设置时钟,如果secs为0,则关闭报警时钟,这样做是很有必要的,如果recvfrom函数读到数据,没到设定时钟值时就返回了,而你又忘记关闭报警时钟的话,那么它将在不久后报警,在计算机看来,1秒都是一个很漫长的时间,1秒后的报警可能会造成本进程中其他函数执行的中断,因为一个进程只有一个定时器,所以使用完定时器后,一定要关闭定时器。
 
实例代码:
int n;
char recvbuf[1024];
static void dealSigAlarm(int signo)
{
 n = -1;
 return;   /* just interrupt the recvfrom() */
}
struct sigaction alrmact;
 bzero(&alrmact,sizeof(alrmact));
 alrmact.sa_handler = dealSigAlarm; 
 alrmact.sa_flags = SA_NOMASK;//使用SA_RESTART将会阻塞在recvfrom函数,与直接使用signal效果相同
 alrmact.sa_restorer = NULL; 
 sigaction(SIGALRM,&alrmact,NULL);
while (1) {
  alarm(5);
  n = recvfrom(peerSocket,recvbuf,1420,0,(struct sockaddr *)&peer_Addr,(socklen_t*)&peer_len)
  if (n < 0) {
   if (errno == EINTR) {
    printf("recvfrom timeout.\n");
   } else {
    printf("recvfrom error.\n");
   }
  }
else {
   alarm(0);//很重要
  }
}
 
附:signal与sigaction函数区别,signal是重启动函数,超时以后会自动启动已阻塞的函数,而不是中断它的执行,比如recvfrom,给人的感觉就是使用了alarm,程序依然阻塞在了recvfrom上,不往下执行,如果在信号处理函数中使用printf可以看到超时后输出了一条超时信息,然后signal又启动了recvfrom,继续阻塞。。。
 
sigaction可以自己设置是否重启动函数,即上面例子中的alrmact.sa_flags = SA_NOMASK选项,SA_NOMASK为不重启动,中断已阻塞的函数recvfrom,使程序继续往下执行,SA_RESTART为重启动函数,与signal相同,继续阻塞在recvfrom上。。。
 


 
  评论这张
 
阅读(2762)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017