C - SIGALRM没有收到
问题描述:
我是新来的信号,我试图在UDP回显服务上设置SIGALRM,作为套接字编程实践。
所以在这里我有一个UDP套接字,客户端发送一个字符串到服务器,并等待响应(任何响应,这里的字符串是由服务器回应)。
目标是设置SIGALRM,并让客户端重新发送字符串几次,如果服务器没有响应或UDP数据包丢失。C - SIGALRM没有收到
在这里,我用了一个小样本,并简化长线,...,你可以在我的github repo(51行)的详细信息
SIGALRM-Client.c
unsigned int tries = 0;
void CatchAlarm()
{
tries += 1;
}
int main(int argc, char **argv)
{
// SKIPPED
// ...
struct sigaction handler;
handler.sa_handler = CatchAlarm;
handler.sa_flags = 0;
if(sigfillset(&handler.sa_mask) < 0)
return 1;
if(sigaction(SIGALRM, &handler, 0) < 0)
return 2;
ssize_t bytes;
bytes = sendto(servSock,...);
while((bytes = recvfrom(servSock,...)) < 0) {
// alarm went off
if(errno == EINTR) {
// try 5 times
if(tries < 5) {
bytes = sendto(servSock,...);
} else {
fprintf(stdout, "no response, waiting...\n");
}
} else {
fprintf(stdout, "failed to get data\n");
return 3;
}
}
// recvfrom() got something, cancel timeout
alarm(0);
fprintf(stdout, "received %d bytes of data\n", bytes);
close(servSock);
}
当我运行客户端时,它不会收到SIGALRM信号,UDP数据包会在第一次尝试中丢失?!
客户端将不会重试发送字符串,然后在5次尝试后退出,而是永远等待服务器响应!
防止客户端获得SIGALRM的原因是什么?
我在这里错过了什么吗?
答
您在GitHub仓库中的代码从不会呼叫alarm()
并带有非零数字。除非您确实要求提供警报信号,否则您将无法自动发送警报信号。依靠其他过程来发送您的过程警报信号不具有弹性。
你有一个'alarm(0)'行。除非我错过了某些东西,否则您从未将闹钟设置为更大的值,因此您不会收到警报信号。 (当然,它可能在你省略的代码中,但你不应该向我们展示不可编译的代码 - 我们需要一个编译和显示你所问的行为的MCVE([MCVE])。 –
@JonathanLeffler你是对的,我应该写一个完整的和可编辑的样本,我认为你的解释已经足够清楚,即使没有完整的代码也是一个答案,我会深入研究信号,并会更加注意使用alarm()函数。谢谢 –