问题来源:UDP编程中,应用程序实现的超时重传机制,在计算每个分组的RTO时。在发送请求和接受应答之间要运用超时重传机制,来提高UDP传输的可靠性。
题外话:【Jacobson算法:每次测得一个RTT后就计算RTO以及重传时如何增加RTO。一般当定时器满,实行RTO指数回退。
Karn算法:只有收到不是重传的请求时,才更新RTT并重新计算RTO。】
使用alarm作为定时器,在对SIGALRM信号处理时,不是希望信号处理函数直接返回,而是希望跳转到主进程。这就需要用到setjmp,longjmp或sigsetjmp和siglongjmp函数。
sigsetjmp和siglongjmp函数应用于信号处理函数中的原因是,使用setjmp,longjmp并不对信号屏蔽字有处理,即捕捉到一个信号后,进入到信号处理函数,内核自动把当前信号加到进程的信号屏蔽字中,避免多次中断,然而在这个时候使用longjmp跳出信号处理函数,信号屏蔽字却没有恢复,使得进程再也捕捉不到这个信号。
int sigsetjmp(sigjmp_buf env, int savesigs);
注意点::::若直接调用则返回0,若用siglongjmp返回则返回非零值
void siglongjmp(sigjmp_buf env, int val);
若savesigs非0,则内核在env中保存了信号的屏蔽字。调用siglongjmp时,siglongjmp从env中恢复信号屏蔽字。
测试1:可以多次捕捉SIGALRM
#include "unp.h"
#include <setjmp.h>
#include <time.h>
sigjmp_buf buf;
void func(int signo){
printf("call func\n");
siglongjmp(buf,1);
printf("next will return func\n");
}
int main(int argc, char **argv){
int nsecs;
signal(SIGALRM, func);
alarm(3);
if(sigsetjmp(buf, 1) == 0){/*调用*/
printf("call success\n");
sleep(10);
}
else{/*从siglongjmp返回*/
printf("siglong jmp return\n");
alarm(0);
alarm(2);
exit(0);
}
}
测试2:第一次SIGALRM捕捉,以后都失去。
#include "unp.h"
#include <setjmp.h>
#include <time.h>
sigjmp_buf buf;
void func(int signo){
printf("call func\n");
longjmp(buf,1);
printf("next will return func\n");
}
int main(int argc, char **argv){
int nsecs;
signal(SIGALRM, func);
alarm(3);
if(setjmp(buf) == 0){/*调用*/
printf("call success\n");
sleep(10);
}
else{/*从siglongjmp返回*/
printf("siglong jmp return\n");
sleep(0);
alarm(2);
alarm(1);
sleep(5);
exit(0);
}
}
关于sigsetjmp,siglongjmp注意点 (UDP超时重传应用)
最新推荐文章于 2022-09-05 17:30:33 发布