【问题标题】:C - SIGALRM not receivedC - 未收到 SIGALRM
【发布时间】:2018-01-01 04:05:06
【问题描述】:

我是信号新手,我正在尝试在 UDP 回显服务上设置 SIGALRM,作为套接字编程实践。
所以这里我有一个 UDP 套接字,客户端向服务器发送一个字符串并等待响应(任何响应,这里的字符串由服务器回显)。
目标是设置 SIGALRM 并让客户端在服务器未做出响应或 UDP 数据包丢失时重新发送字符串几次。

在这里,我使用了一个小样本并将长行简化为 ...,您可以在我的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?
我在这里错过了什么吗?

【问题讨论】:

  • 您有一个alarm(0) 行。除非我遗漏了什么,否则您从未将警报设置为更大的值,因此您不会收到警报信号。 (当然,它可能在您省略的代码中,但您不应该向我们展示不可编译的代码——我们需要一个 MCVE (minimal reproducible example) 来编译并显示您所询问的行为。)
  • @JonathanLeffler 你是对的,我应该写一个完整且可编译的示例,我认为你的解释很清楚,即使没有完整的代码也可以作为答案,我会更深入地研究信号并将更加注意使用alarm()函数。谢谢

标签: c sockets signals nonblocking


【解决方案1】:

您在 GitHub 存储库中的代码从不使用非零数字调用 alarm()。除非您确实请求,否则您永远不会自动发出警报信号。依靠其他进程向您的进程发送警报信号是没有弹性的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-21
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    相关资源
    最近更新 更多