C UDP-сокеты: произвольное поведение setsockopt (с SO_RCVTIMEO)

SO_RCVTIMEO просто не создает условие тайм-аута в моих функциях вывода. Я разрабатываю службу передачи файлов с использованием протокола скользящего окна ARQ. Чтобы все было в порядке, я начинаю с базовой стратегии «Остановись и подожди».

Это моя инициализация timeval

    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 100000;

Это мое использование этой структуры и сокета при подготовке тайм-аута recvfrom

if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))<0)
{
fprintf(stderr, "Error in socket option for Timeout mechanism: %s",strerror(errno));
close(sock);
exit(EXIT_FAILURE);
}

if (-1 == bind(sock,(struct sockaddr *)&sa, sizeof(sa)))
{
    perror("error bind failed");
    close(sock);
    exit(EXIT_FAILURE);
}

Это тело кода, которое должно истечь по тайм-ауту:

for(;;)
{
...
while((read_bytes=fread((char*)&(packet.body),sizeof(char),CHUNKSIZE,out_file))
{
...
while(1)
{
bytes_sent = sendto(sock, (struct sanpacket*)&packet, sizeof(struct sanpacket), 0,(struct sockaddr*)&sa, sizeof sa);
if (bytes_sent < 0) 
{
    fprintf(stderr, "%s\n", strerror(errno));
    exit(EXIT_FAILURE);
}
printf("Waiting for ACK packet\n");

recsize = recvfrom(sock, (struct sanpacket*)&packet, sizeof(struct sanpacket), 0, (struct sockaddr*)&sa, &fromlen);
if(errno == EAGAIN)
{
    printf("Timed out; resending packet with sequence number %d", packet.sequence_num);
    continue;
}
if (recsize < 0) 
{
    fprintf(stderr, "%s\n", strerror(errno));
    exit(EXIT_FAILURE);
}

}

Проблема: тайм-аут не срабатывает, но setsockopt также не возвращает никаких ошибок. У меня нет возможности узнать, что я делаю неправильно.

Если есть что-то еще, что я могу сделать, чтобы прояснить мой вопрос или окружающую среду, пожалуйста, дайте мне знать. И я был бы признателен, если бы у вас были какие-либо предложения по отладке этого.


person Regress.arg    schedule 25.08.2014    source источник
comment
1. .1 секунды слишком мало для тайм-аута чтения. 2. Проверка errno недействительна, если системный вызов не вернул -1. 3. Отличается ли EWOULDBLOCK от EAGAIN в вашей системе?   -  person user207421    schedule 26.08.2014
comment
1. См. эту ссылку: stackoverflow.com/questions/13547721/udp- тайм-аут набора сокетов 2a. Не могли бы вы уточнить это? Я думал, что проверяю errno после вызова recvfrom. (Если recvfrom не один, то какие у меня другие варианты?) 2b. Даже если бы это было так, почему тайм-аут не сработает независимо, а затем не завершится второй оператор if? Возвращаемое значение recvfrom после параметра сокета равно -1. 3. Для Linux (не уверен насчет Cygwin) EWOULDBLOCK идентичен EAGAIN.   -  person Regress.arg    schedule 26.08.2014
comment
1. Это все еще слишком мало, кроме, может быть, тестовых целей. Реальный таймаут чтения измеряется несколькими секундами. 2а. Тест errno должен находиться внутри блока if (recsize < 0). 2б. Я не понимаю вопроса.   -  person user207421    schedule 26.08.2014


Ответы (1)


Фон, который я забыл упомянуть, заключается в том, что это компилировалось на Debian Linux, а не на платформе Cygwin, которую я хотел использовать.

Вот я и задумался над этой совершенно неразрешимой проблемой. Затем я вспомнил бритву Оккама и подумал, что может быть самым простым, самым простым объяснением того, что происходит?

Как оказалось, Cygwin не поддерживает таймауты setsockopt.

Я бы сказал кое-что о необходимости системы, с помощью которой вы можете апеллировать к разработчикам на часы своей жизни, но это несущественно, и в любом случае Cygwin — прекрасный симулятор Linux, кроме того.

person Regress.arg    schedule 26.08.2014