コンピュータネットワークプロジェクトでは、さまざまなウィンドウプロトコルを使用してc++でftpサーバーを作成しています。動作するタイムアウト関数の実装に問題があります。その要点は、パケットが送信されるときにタイムスタンプを設定することです。「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ループを変更して、タイムアウト+タイムスタンプが許可されている長いinteregerサイズよりも大きいかどうかを確認し、比較の前にclock_gettimeがゼロに戻るかどうかを確認します。これを知って、現在の時刻>(タイムアウト間隔-(maximum long int val-タイムスタンプ))かどうかを確認しました。これにより、最大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;
}