C - SIGALRM未收到

时间:2017-07-26 03:00:07

标签: c sockets signals nonblocking

我是信号新手,我正在尝试在UDP echo服务上设置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?
我在这里错过了什么吗?

1 个答案:

答案 0 :(得分:2)

GitHub repo中的代码从不使用非零数字调用alarm()。除非你真的要求,否则你永远不会自动发出警报信号。依靠其他一些过程来发送您的过程警报信号不具备弹性。