Реализация тайм-аута пакетов c

#c #timeout #packets

#c #тайм-аут #пакеты

Вопрос:

Для проекта компьютерных сетей мы пишем ftp-сервер на c с различными протоколами window. У нас возникли проблемы с реализацией рабочей функции тайм-аута. Суть этого заключается в том, чтобы установить временную метку на момент передачи пакета, и если «подтверждение» не восстанавливается в течение определенного промежутка времени (скажем, 2,5 миллисекунд), повторно передать пакет. В настоящее время мы используем clock_gettime() функцию для получения текущего времени и временной метки пакета.

Вот цикл while, с которым у нас возникают проблемы:

 while(packet_sync_array[prev].recieved ==0 amp;amp; t==0)
{
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID,amp;timeout2);
    currtime = timeout2.tv_nsec;
    cout << "Is currtime: "<<currtime<< " - ptimeout " << ptimeout 
         << " = " << (currtime - ptimeout) << " > " 
         << (connection_parameters->timeoutInterval)*1000 << "?" << endl;

    if((currtime - ptimeout)>((connection_parameters->timeoutInterval)*1000))
    {
        t = 1;
        cout << "Prev PACKET TIMEDOUT" << endl;
        cout << "Is currtime: "<<currtime<< " - ptimeout " << ptimeout 
             << " = " << (currtime - ptimeout) << " > " 
             << (connection_parameters->timeoutInterval)*1000 << "?" << endl;
    }
}  
  

Где ptimeout — время отправки пакета и connection_parameters->timeoutInterval — интервал тайм-аута. Проблема в том, что, поскольку ptimeout это длинное целочисленное представление времени, иногда это очень большое значение (например, 999715992). Это означает, что он никогда не сможет определить, наступил ли тайм-аут, потому что текущее время в наносекундах будет равно 0, прежде чем значение станет достаточно большим.

Кто-нибудь еще сталкивался с этими проблемами синхронизации в c и у него есть возможное решение?

Спасибо!

Редактировать:

Спасибо за быстрые ответы! Я смог кое-что выяснить. Изменение цикла while, чтобы проверить, будет ли тайм-аут временная метка больше допустимого размера интервала long, позволяет мне посмотреть, получит ли clock_gettime откат к нулю перед сравнением. Зная это, я проверил, соответствует ли текущее время > (интервал тайм-аута — (максимально длинное значение int val — отметка времени)). Это допускает тайм-аут до 1 секунды, которого должно быть достаточно для решения этой проблемы. Если кто-нибудь думает, что у них есть лучшее решение, дайте мне знать! Спасибо! Вот код для тех, кому интересно:

 if(((999999998-ptimeout)< (connection_parameters->timeoutInterval)*1000)amp;amp;(currtime - ptimeout)<0){
          if(currtime > (((connection_parameters->timeoutInterval)*1000)-(999999998-ptimeout))){
              t = 1;
              cout << "this wrapped since " << currtime << "   " << (connection_parameters->timeoutInterval)*1000 << "is bigger than 999999999 and then timed out" << endl;
              cout << "curr time " << currtime << "is bigger than" << endl;
              cout << (connection_parameters->timeoutInterval)*1000 << endl;
              cout << "-" << endl;
              cout << (999999998-ptimeout) << endl;
              cout << "---------------------------" << endl;
              cout << (((connection_parameters->timeoutInterval)*1000)-(999999998-ptimeout)) << endl;
              cout << "Prev PACKET TIMEDOUT" << endl;
              cout << "Is currtime: "<<currtime<< " - ptimeout " << ptimeout << " = " << (currtime - ptimeout) << " > " << (connection_parameters->timeoutInterval)*1000 << "?" << endl;
          }
      }
      else if((currtime - ptimeout)>((connection_parameters->timeoutInterval)*1000)){
       t = 1;
       cout << "Prev PACKET TIMEDOUT" << endl;
       cout << "Is currtime: "<<currtime<< " - ptimeout " << ptimeout << " = " << (currtime - ptimeout) << " > " << (connection_parameters->timeoutInterval)*1000 << "?" << endl;
      }
  

Комментарии:

1. Я, конечно, не профи в сетевых вещах, но я почти уверен, что TCP / IP позаботится об обработке потерянных пакетов. Почему вы не полагаетесь на это?

2. @Joce они бы ничего не узнали о сетевых протоколах, если бы просто использовали предварительно упакованный 🙂

3. @Joce: «Для проекта компьютерных сетей мы пишем ftp-сервер на c с различными оконными протоколами». — «окно» будет означать временное окно для повторной отправки; они намеренно переопределяют часть функциональности TCP, чтобы узнать, как это сделать.

4. @Jeremy @Tony Видишь ли, я ничего не знаю о сети! 🙂

Ответ №1:

возможно, вы захотите изменить свой код, чтобы сказать:

 // time in microseconds
currtime = timeout2.tv_sec * 1000000   timeout2.tv_nsec / 1000;
  

Просто убедитесь, что вы не получаете никаких переполнений целых чисел! Вероятно, хорошей идеей будет явно преобразовать, например, в 64-битное целое число.

Кроме того, вы, скорее всего, хотите, чтобы тайм-аут был по крайней мере на порядок больше 2,5 миллисекунд, возможно, больше. Ваш временной интервал в операционной системе, скорее всего, составит где-то около 17 миллисекунд, например, не говоря уже о задержках в сети.

Ответ №2:

Вам нужно посмотреть как на tv_sec , так и на tv_nsec компоненты timespec объекта, который clock_gettime заполняет. Ваше ptimeout поле должно быть timespec , а не целым числом. Вам придется писать функции для выполнения математики над timespec объектами, я не думаю, что есть что-то запасное.