Реализация тайм-аута пакета c ++ - PullRequest
2 голосов
/ 20 апреля 2011

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

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

while(packet_sync_array[prev].recieved ==0 && t==0)
{
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&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 для проверки и просмотра того, будет ли timeout + timestamp больше допустимого длинного целочисленного размера, позволит мне увидеть, будет ли clock_gettime возвращаться к нулю перед сравнением.Зная это, я проверил, является ли текущее время> (интервал тайм-аута (максимальный длинный интервал - метка времени)).Это допускает время ожидания до 1 секунды, которого должно быть достаточно для решения этой проблемы.Если кто-то думает, что у него есть лучшее решение, дайте мне знать!Спасибо!Вот код для заинтересованных:

if(((999999998-ptimeout)< (connection_parameters->timeoutInterval)*1000)&&(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;
      }

Ответы [ 2 ]

3 голосов
/ 20 апреля 2011

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

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

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

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

1 голос
/ 20 апреля 2011

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

...