0
votes

I'm new to signals, I'm trying to set SIGALRM on UDP echo service, as a socket programming practice.
So here I have a UDP socket, the client sends a string to server and waits for response (any response, here the string is echoed by server).
The goals is to set SIGALRM and let the client resend the string a few times if no responses were made by server or UDP packets get lost.

Here, I used a small sample and simplified long lines with ..., you can get more details on my github repo (line 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);
}

When I run the client, it won't receive SIGALRM signal and UDP packets get lost in first attempt?!
Client won't retry sending string then exit after 5 attempts, instead, it waits for server response forever!
What prevents client to get SIGALRM?
Did I miss something here?

1
You have an alarm(0) line. Unless I'm missing something, you've never set the alarm to a bigger value, so you don't get an alarm signal delivered. (Of course, it could be in the code you omitted, but you should not be showing us non-compilable code — we need an MCVE (minimal reproducible example) that compiles and displays the behaviour you're asking about.)Jonathan Leffler
@JonathanLeffler you're right, I should have written a complete & compilable sample, well I think your explanation is clear enough to be an answer even without complete code, I will go deeper in signals and will pay more attention to using alarm() function. thanksBrian SP

1 Answers

2
votes

Your code in the GitHub repo never calls alarm() with a non-zero number. You'll never get an alarm signal delivered automatically unless you actually request one. Relying on some other process to send your process an alarm signal isn't resilient.