Установка таймаута для сокета не работает - PullRequest
0 голосов
/ 28 февраля 2019

Я использую функцию setsockopt(), чтобы установить время ожидания для функции recvfrom().Из-за протокола, который я использую, у меня сначала должно быть время ожидания 2 секунды, затем 4, 6, до макс.Но когда я использую эту функцию, кажется, что у нее тайм-аут 0,01 секунды, потому что она отправляет 8 пакетов без ожидания.

//more variables and code here
struct timeval timeout = {2,0};

while(1){
  setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval));
  temp2 = recvfrom(sock, &buff, sizeof(buff), 0, (struct sockaddr *)&addr_server, sizeof(addr_server));

  if(temp2 < 0){ /* Timeout excedit (exceeded)*/
      temp = sendto(sock, (struct udp_PDU*)&reg_pdu, sizeof(reg_pdu), 0, (struct sockaddr *)&addr_server, sizeof(addr_server));
      if(temp == -1){
        printf("Error sendTo \n");
        exit(-1);
      }
      packet_counter++;
      debug("Enviat paquet REGISTER_REQ");
      if(packet_counter == 8) break;
      if((interval * max) > t ) timeout.tv_sec+=interval;

  }else{ /* s'han rebut dades (they have rebooted) */
    correct = 1;
    break;
  }
}

1 Ответ

0 голосов
/ 28 февраля 2019

Тайм-аут (например, то, что вы реализуете.) Не является оператором задержки.Скорее, это метод предотвращения блокировки вызовов, таких как recv() или recvfrom(), на неопределенный срок.Если трафик данных обнаруживается раньше, чем установлен тайм-аут, тем лучше.Функция получает его, и выполнение программы продолжается.Тайм-аут, как он есть, ждет до 2 секунд, чтобы что-то произошло.Если ничего не происходит, то он позволяет методу прекратить ожидание и продолжить выполнение вашей программы, то есть он не блокируется.Без таймаута такие функции, как recv() или recvfrom() могут блокироваться навсегда.

Если вы хотите задать 2-секундный интервал (или блок ) между вызовами recvfrom() и sendto(), поместите sleep (2); (или, если в Windows, оператор Sleep (2000); ) где-то в вашем цикле, возможно, в нижней части.

while(1){
    ...
    }
    sleep(2);  //or on Windows, Sleep(2000);
}

BTWТакже рекомендуется регулярно проверять возвращаемое значение любой функции, которая имеет такую ​​функцию, в частности, если сбой этой функции приведет к хаосу в остальной части вашего кода.Например:

if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(struct timeval)) < 0) {
    perror("Error");
}
...

Несколько связанных тем:

...