Тайм-аут гнезда 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++;
}
Ответы
Ответ 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());
}