|
蓝森林 http://www.lslnet.com 2006年8月16日 14:08
|
|
recvfrom重发定时SIGALRM并不能准时到来为什么?
|
|
#define TIMEOUT 20/*20 seconds*/
truct sigaction sa_old;
struct sigaction sa_new;
nrtn=0;
sa_new.sa_handler=sigalrm;
sigemptyset(&sa_new.sa_mask);
sigaddset(&sa_new.sa_mask,SIGALRM);
sa_new.sa_flags=0;
sigaction(SIGALRM,&sa_new,&sa_old);
alarm(OUTTIMEVAL);
if((nrtn=recvfrom(socket,pkgrcvbuff,nwilbercv,\
(blrcvpeek?MSG_PEEK:0)|MSG_WAITALL,\
(struct sockaddr*)&sockaddr,&sockaddrlen))<0)
/* NULL,NULL))<0) */
{
if(errno==EINTR)
{
alarm(0);
sigaction(SIGALRM,&sa_old,NULL);
return -2;/* time out */
}
else
{
printf("client:recvfrom error %s.\n",strerror(errno));
alarm(0);
sigaction(SIGALRM,&sa_old,NULL);
return -1;
}
}
alarm(0);
sigaction(SIGALRM,&sa_old,NULL);
static void sigalrm(int signo)
{
printf("TIME OUT.\n");
return;/* just interrupt the recvfrom() function */
}/* end sigalrm() */
好像recvfrom一直阻塞了,不能被SIGALRM信号中断,只是偶尔能打印出TIME OUT来,也就是说不能
返回-2(return -2)进行重发。
在我这种情况下使用select定时不方便。怎么才能使SIGALRM按时的中断recvfrom实现自动重发呢,欢迎
ejiang指点,欢迎各位大虾指点。谢谢。
run brain
|
|
|
Re: recvfrom重发定时SIGALRM并不能准时到来为什么?
|
|
First of all, alarm() should work. I've tested it on my box.
Your real problem is under Linux, the default sigaction's sa_flags is SA_RESTART, so recvmsg() will restart after your SIGALRM's handler. So, your current program will never reach "return -2".
If you want to use alarm signal to interrupt your recvfrom() call, you need to specify the sa_flags = SA_INTERRUPT explicitly (Actually, in Linux's kernel, SA_INTERRUPT is ignored, so basically sa_flags = 0 should work too. But, specifiying it to SA_INTERRUPT is a good behavior to make your program be compatible with other platform)
I don't know your kernel's version yet. Basically under linux2.2.x you can not use setsockopt() to specify the socket's SO_RCVTIMEO, as same RCVLOWAT ;), you do can do that in linux2.4.x.
EJ
-------------------------
There's no spoon
- The Matrix
-------------------------
|
|
|
Re: recvfrom重发定时SIGALRM并不能准时到来为什么?
|
|
linux kernel is 2.2.16-22
run brain
|
|