实现数据包超时 c++
对于一个计算机网络项目,我们正在用 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 循环来检查超时+时间戳是否大于允许的长整数大小,让我看看在比较之前clock_gettime是否会回落为零。知道这一点后,我检查了当前时间是否> (超时间隔 - (最大 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;
}
For a computer networks project, we are writing an ftp server in c++ with different window protocols. We are having issues implementing a working timeout function. The gist of it is to set a timestamp to when a packet is transmitted, and if the "ack" isn't revived in a certain amount of time (say 2.5 milliseconds), retransmit the packet. We currently use the clock_gettime()
function to get the current time and timestamp the packet.
Here is the while loop we are having issues with:
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;
}
}
Where ptimeout
is the time that the packet was sent and connection_parameters->timeoutInterval
is the timeout interval. The problem is that since ptimeout
is a long integer representation of the time, sometimes it is a very large value (999715992 for example). This means that it will never be able to tell if the timeout has occurred, because the current time in nano seconds will be rest to 0 before the value gets large enough.
Has anyone else dealt with these timing issues in c++ and have a possible solution?
Thanks!
EDIT:
Thanks for the quick responses! I was able to get something figured out. Modifying to the while loop to check and see if the timeout+the timestamp would be larger than the allowed long intereger size let me see if the clock_gettime would get setback to zero before the comparison. Knowing this I checked if the current time > (timeout interval - (maximum long int val - time stamp)). This allows for a timeout of up to 1 second which should be plenty for the purposes of this problem. If anyone thinks they have a better solution, let me know! Thanks!
Here is the code for those interested:
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可能想将代码更改为:
只要确保没有任何整数溢出即可!例如,显式转换为 64 位整数可能是个好主意。
此外,您很可能希望超时至少比 2.5 毫秒大一个数量级,甚至可能更多。例如,您在操作系统中的时间片很可能约为 17 毫秒,更不用说网络延迟了。
you might want to change your code to say:
Just make sure you don't get any integer overflows! It's probably a good idea to explicitly cast to a 64 bit integer for instance.
Also, you most likely want a timeout at least one order of magnitude larger than 2.5 milliseconds, probably more. Your time slice in the operating system will most likely be somewhere around 17 milliseconds for instance, not to speak of network latencies.
您需要查看
clock_gettime
填充的timespec
对象的tv_sec
和tv_nsec
组件。 code>ptimeout 字段应该是timespec
而不是整数。您必须编写函数来对timespec
对象进行数学运算,我认为没有任何库存。You need to look at both the
tv_sec
andtv_nsec
components of thetimespec
object thatclock_gettime
fills in. Yourptimeout
field should be atimespec
rather than an integer. You'll have to write functions to do math ontimespec
objects, I don't think there's anything stock.