У меня есть signal
, где я устанавливаю обработчик обратного вызова, а затем в своей функции я вызываю alarm(1)
, чтобы моя программа истекла через 1 секунду.По истечении времени ожидания я бы хотел, чтобы он повторил тот же самый блокирующий вызов recvfrom()
до набора MAX_ATTEMPTS
, равного 5.
Проблема:
Это только повторные попытки2 раза до выхода из программы.Любая идея, что может пойти не так?
/* declate signal for setting alarm */
signal(SIGALRM, timeout_hdler);
int attempts = 0;
while(1) {
if(attempts > MAX_ATTEMPTS) {
printf("Connection is not working, EXITING program");
s.curr_state = CLOSED;
/* we assume connection is failing so we shut down */
exit(-1);
}
if (s.curr_state == CLOSED) {
printf("Sending SYN_packet with seqnum: %d...\n", SYN_packet->seqnum);
if (sendto(sockfd, SYN_packet, sizeof(SYN_packet), 0, server, socklen) == -1) {
perror("Sendto error");
exit(-1);
}
s.curr_state = SYN_SENT;
printf("Current state SYN_SENT: %d\n", s.curr_state);
}
if (s.curr_state == SYN_SENT) {
alarm(1);
attempts++;
printf("\nAttempt number: %d\n", attempts);
printf("Waiting for SYNACK_packet...\n");
if (recvfrom(
sockfd, SYNACK_packet, sizeof(*SYNACK_packet), 0, (struct sockaddr *) &server, &socklen) == -1)
{
if (errno != EINTR) {
perror("Recvfrom SYNACK_packet error\n");
s.curr_state = CLOSED;
exit(-1);
}
}
if ((SYNACK_packet->type == SYNACK) && (validate_packet(SYNACK_packet) == 1)) {
printf("SYNACK_packet received\n");
s.address = *(struct sockaddr *) &server;
s.sock_len = socklen;
s.curr_state = ESTABLISHED;
s.seq_num = SYNACK_packet->seqnum;
printf("Current state ESTABLISHED: %d\n", s.curr_state);
return sockfd;
}
}
}
Обработчик (который ничего не делает, кроме печати):
void timeout_hdler(int signum) {
printf("TIMEOUT has occured with signum: %d", signum);
}
Вот вывод в моей консоли (из printf
оператор):
In Connect() with socket: 4, server: 2, socklen: 16
Sending SYN_packet with seqnum: 67...
Current state SYN_SENT: 1
Attempt number: 1
Waiting for SYNACK_packet...
TIMEOUT has occured with signum: 14
Attempt number: 2
Waiting for SYNACK_packet...
Alarm clock
Почему он выходит из программы только после 2 попыток?В идеале я хотел бы повторить попытку 5 раз перед закрытием соединения (это реализация Go Back N с использованием UDP)
UPDATE
Я решил проблему путем переустановкиsignal
: signal(SIGALRM, timeout_hdler);
в моем обработчике.Но почему это так?Я делаю это неправильно?
void timeout_hdler(int signum) {
printf("TIMEOUT has occured with signum: %d", signum);
signal(SIGALRM, timeout_hdler);
}