Подтвердить что ты не робот

Тайм-аут гнезда UDP

Я пытаюсь установить тайм-аут 100 мс на UDP-сокет. Я использую C. Я разместил ссылки на мои фрагменты ниже. Я не уверен, почему это не время, но просто зависает, когда он не получает сегмент. Это работает только на сокетах, которые не связаны с помощью метода bind()?

#define TIMEOUT_MS      100     /* Seconds between retransmits */

if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    DieWithError("socket() failed");

if ((rcv_sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
    DieWithError("socket() failed");

//set timer for recv_socket
static int timeout = TIMEOUT_MS;
setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));

if(recvfrom(rcv_sock, ackBuffer,sizeof(ackBuffer), 0,
       (struct sockaddr *) &servAddr2, &fromSize) < 0){
    //timeout reached
    printf("Timout reached. Resending segment %d\n", seq_num);
    num_timeouts++;
}
4b9b3361

Ответ 1

Параметр SO_RCVTIMEO ожидает struct timeval, определенный в sys/time.h, а не целое число, подобное тому, которое вы передаете ему. timeval struct имеет поле в секундах и поле для микросекунд. Чтобы установить тайм-аут на 100 мс, следующее должно выполнить трюк:

struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 100000;
if (setsockopt(rcv_sock, SOL_SOCKET, SO_RCVTIMEO,&tv,sizeof(tv)) < 0) {
    perror("Error");
}

Ответ 2

У меня точно такая же проблема. Я попытался принять предложенное вами решение, используя структуру timeval. Но это не похоже на работу.

Я прочитал документацию Microsoft, и время должно быть DWORD с количеством миллисекунд, но есть еще одна вещь, которую нужно сделать: если сокет создается с использованием функции WSASocket, то параметр dwFlags должен иметь атрибут WSA_FLAG_OVERLAPPED, установленный для таймаута для правильной работы.  В противном случае тайм-аут никогда не вступает в силу.

Ответ 3

Я знаю, что это старая ветка, но в случае, если кто-то хочет рабочий код:

int timeout = 5000; // 5 seconds

if (setsockopt(socketVar, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(int)) == SOCKET_ERROR)
{
    printf("Timeout setting failed, code %d\n", WSAGetLastError());
}