Для проекта компьютерных сетей мы пишем 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;
}