我正在使用这种在C#中返回NTP时间作为DateTime对象的实现: https://stackoverflow.com/a/12150289/559988
然而,由于这是在我无法控制的网络上的许多计算机上的软件中部署的,因此问题变得有时NTP有时会在这些网络上被阻止。因此,当调用该方法时,它似乎永远不会返回,因为它永远不会获得任何数据。
我尝试按如下方式实现超时:
IAsyncResult result = socket.BeginConnect(ipEndPoint, null, null);
Boolean success = result.AsyncWaitHandle.WaitOne(15000,true);
if (!success)
{
socket.Close();
throw new ApplicationException("Failed to connect to NTP server within 15 seconds");
}
但是超时不起作用,因为该方法没有返回。
有谁知道如何为Socket实现超时,以便我至少可以故障转移到另一种检查NTP时间的方法?
由于
编辑:只是为了澄清是否没有网络连接(即你禁用你的适配器)它会立即失败就好了。这是一个网络问题,一些网络正在阻止NTP协议(我认为)导致套接字打开但挂起在任一连接上或等待接收数据。
答案 0 :(得分:2)
我相信你实施的超时不起作用,因为该方法总是立即返回。
UDP协议是无连接的。当您在UDP套接字上调用Connect()
时,实际上没有任何事情发生,您只需设置一个默认端点,这样就不会在每次Send()
呼叫时重复自己。
Send()
调用也会很快返回,即使远程主机无法访问也是如此。在这种情况下,数据将丢失,这就是UDP的工作方式。
底线:
您需要在Receive()
电话上实施超时:
var result = socket.BeginReceive(ntpData, 0, ntpData.Length, SocketFlags.None, null, null);
var success = result.AsyncWaitHandle.WaitOne(15000);
if (!success)
{
socket.Close();
throw new ApplicationException("Failed to connect to NTP server within 15 seconds");
}