2012-08-28 78 views
1

我正在开发通过UDP从NTP服务器获取时间戳的SNTP客户端。一切正常,我可以下载时间戳和更新Windows时钟,但是如果UDP数据包丢失了,我希望得到一条消息。如何检测包何时丢失?我需要这些信息,因为如果数据丢失,我想获得新的时间戳。如何检测UDP数据包已丢失? (C#)

...以及如何测试该功能?如何故意丢失UDP数据包?

+4

UDP是单向的,你可以没有检测到包丢失。这是TCP和UDP之间的主要区别。 –

+0

这个服务究竟是如何工作的?请问您的客户端向服务器的请求,并等待响应,之后更新它的时间?或者您的客户端是否等待并侦听来自服务器的UDP数据包?无论哪种方式,您都无法真正验证UDP数据包的传输。根据您的需求,设置超时可能对您来说可能是更好的选择?如果在最近的X秒内没有更新时间或者类似的东西,显示警告或抛出异常或其他内容? – Kjartan

回答

8

这是UDP无法实现的。如果你需要一个可靠的连接,你应该使用TCP。

+0

+1,尽管您仍然可以实现与序列号的连接,通过UDP进行确认和重新传输。尽管这没有意义,但我必须将其作为实验任务来完成(许多小时和测试几乎与TCP一样好,这是真正的痛苦)。 – NotGaeL

1

UDP是无连接协议。当没有连接时,你无法“检测”任何东西。您必须使用面向连接的协议(如TCP)才能解决此问题。

Comparison

0

好的。我知道了。但是我可以通过做这样的事情来检查丢包情况吗?例如,如果我将计时器设置为2秒,然后运行此功能,我可以看到服务器是否正确响应。那我应该知道是否有包丢失?

public bool IsResponseValid() 
    { 
     if(SNTPData.Length < SNTPDataLength || Mode != _Mode.Server) 
     { 
      return false; 
     } 
     else 
     { 
      return true; 
     } 
    } 
+0

无法抗拒优化代码的冲动: return SNTPData.Length> = SNTPDataLength && Mode == _Mode.Server; – rmp251

5

你有三个选择:

  1. 忽略丢弃的数据包
  2. 使用TCP而不是
  3. 建立自己的检测系统

什么你问是怎么做的#3,答案是:

  • 向每个数据包添加数据包号和数据包时间戳。
  • 创建一个数据包栈,并将传入的数据包插入按数据包编号排序的堆栈中。
  • 只有当分组号为(最后一个分组号+ 1)的分组时,才从堆栈中删除分组。
  • 如果数据包存在间隙并且(gap + 1)数据包的时间戳大于某个阈值,则发送“重新传输请求”数据包以重新传输丢弃的数据包。

搁置一秒..这就是TCP的确如此(*)!你应该只使用TCP!

(*),这是一种简化,TCP不工作的很大,使这一进程可靠。

0

因为没有办法测试,如果UDP没有到达,唯一真正的选择是前面加上“包号”和发送的所有数据,因此如果它不符合下一个号码,你知道它失去了包..

据我所知,有没有办法故意输掉1个UDP数据包时,除了猛拉电缆和更换..和希望..