我正在使用下面的代码来查询 NTP 服务器。这段代码工作正常,直到我为 NTP 服务器传递一个无效的主机名:然后这段代码需要很长时间。

const string ntpServer = "pool.ntp.org";

var ntpData = new byte[48];
ntpData[0] = 0x1B; //LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode)

var addresses = Dns.GetHostEntry(ntpServer).AddressList;
var ipEndPoint = new IPEndPoint( addresses[0] , 123);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,  ProtocolType.Udp);

socket.Connect(ipEndPoint);
socket.Send(ntpData);
socket.Receive(ntpData);
socket.Close();

ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43];
ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47];

var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
var networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);
Label1.Text = networkDateTime.ToString();

我收到以下错误

最佳答案

更新 - 新信息

啊,您得到的等待可能是由于 DNS 超时尝试解析主机地址。

您收到的错误可能是因为无法解析域名。

参与编写防御性代码的实践是个好​​主意。无论哪里有可能为空,抛出异常或您做出假设。

原始答案

UDP 是一种无连接协议(protocol),没有任何内置的错误处理。

由于您的代码使用 UDP,因此它不知道它是否成功地向 NTP 服务器发送了请求,并且默认情况下将永远等待响应。我猜你是在自己杀死这个过程。

你唯一能做的就是设置一个 ReceiveTimeout 并在它发生时捕获异常。

const string ntpServer = "pool.ntp.org";
const int timeout = 2000;

var ntpData = new byte[48];
ntpData[0] = 0x1B; //LeapIndicator = 0 (no warning), VersionNum = 3 (IPv4 only), Mode = 3 (Client Mode)

IPHostEntry dnsLookup = null;
try {
    dnsLookup = Dns.GetHostEntry(ntpServer);
}
catch(Exception e){ //Better to catch specific types of exceptions
    Label1.Text = string.Format("Unable to resolve hostname: {0}, ntpServer)";
}

if (dnsLookup == null || dnsLookup.AddressList.Length == 0){
    return;
}

var ipEndPoint = new IPEndPoint(dnsLookup.AddressList[0], 123);
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram,  ProtocolType.Udp);

// wait two seconds before timing out
socket.ReceiveTimeout = timeout;

try{
    socket.Connect(ipEndPoint);
    socket.Send(ntpData);

    socket.Receive(ntpData);
    ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43];
    ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47];

    var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
    var networkDateTime = (new DateTime(1900, 1, 1)).AddMilliseconds((long)milliseconds);
    Label1.Text = networkDateTime.ToString();
}
catch(Exception e){ //Better to catch specific types of exceptions
    Label1.Text = string.Format("Unable to get time from NTP server: {0}, ntpServer)";
}
finally{
    socket.Close();
}

关于c# - NTP 查询在传递无效主机名时需要很长时间,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31335375/

10-13 07:08