0

我在 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 协议(​​我认为)导致套接字打开但挂在连接上或等待接收数据。

4

1 回答 1

2

我相信您实现的超时不起作用,因为该方法总是立即返回。

UDP 协议是无连接的。当您调用Connect()UDP 套接字时,实际上什么都没有发生,您只是设置了一个默认端点,因此您不会在每次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");
}
于 2013-10-28T18:32:04.053 回答