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的原因是什么?
我在这里错过了什么吗?

+1

你有一个'alarm(0)'行。除非我错过了某些东西,否则您从未将闹钟设置为更大的值,因此您不会收到警报信号。 (当然,它可能在你省略的代码中,但你不应该向我们展示不可编译的代码 - 我们需要一个编译和显示你所问的行为的MCVE([MCVE])。 –

+0

@JonathanLeffler你是对的,我应该写一个完整的和可编辑的样本,我认为你的解释已经足够清楚,即使没有完整的代码也是一个答案,我会深入研究信号,并会更加注意使用alarm()函数。谢谢 –

您在GitHub仓库中的代码从不会呼叫alarm()并带有非零数字。除非您确实要求提供警报信号,否则您将无法自动发送警报信号。依靠其他过程来发送您的过程警报信号不具有弹性。