我使用以下代码查询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();
我收到以下错误
在&#39; /&#39;中显示以下错误msgServer错误应用。没有这样的主机已知说明:在执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。异常详细信息:System.Net.Sockets.SocketException:未知此类主机源错误:第26行:ntpData [0] = 0x1B; // LeapIndicator = 0(无警告),
答案 0 :(得分:3)
更新 - 新信息
啊,你得到的等待可能是由于DNS超时尝试解析主机地址。
您获得的错误可能是因为无法解析域名。
参与编写防御性代码的做法是一个好主意。无论在哪里都有可能出现空值,抛出异常或做出假设。
原始回答
UDP是一种无连接协议,没有任何内置的错误处理。
由于您的代码使用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();
}