📜  NTP 查询 - 任何代码示例

📅  最后修改于: 2022-03-11 14:56:39.140000             🧑  作者: Mango

代码示例1
using System;using System.Diagnostics;using System.Net;using System.Net.Sockets;using System.Threading.Tasks; namespace CheckTimeServer.Console{    public static class Program    {        public static async Task Main(string[] args)        {            //            // Example usage:            //             var networkTime = await GetNetworkTime();            if (networkTime.HasValue)            {                var localZone = TimeZoneInfo.Local;                 System.Console.WriteLine("Network time: {0} ({1})", networkTime.Value,                    localZone.IsDaylightSavingTime(networkTime.Value)                        ? localZone.DaylightName                        : localZone.StandardName);            }            else            {                System.Console.WriteLine("Could not retrieve network time.");            }             System.Console.ReadKey();        }         private static async Task GetNetworkTime(string ntpServer = "pool.ntp.org")        {            // https://stackoverflow.com/questions/1193955/how-to-query-an-ntp-server-using-c             if (ntpServer == null)            {                throw new ArgumentNullException(nameof(ntpServer));            }             try            {                const int daysTo1900 = 1900 * 365 + 95; // 95 = offset for leap-years etc.                const long ticksPerSecond = 10000000L;                const long ticksPerDay = 24 * 60 * 60 * ticksPerSecond;                const long ticksTo1900 = daysTo1900 * ticksPerDay;                 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);                // ReSharper disable once RedundantAssignment                 var pingDuration = Stopwatch.GetTimestamp(); // temp access (JIT-Compiler need some time at first call)                 using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))                {                    await socket.ConnectAsync(ipEndPoint);                    socket.ReceiveTimeout = 5000;                    socket.Send(ntpData);                    pingDuration = Stopwatch.GetTimestamp(); // after Send-Method to reduce WinSocket API-Call time                     socket.Receive(ntpData);                    pingDuration = Stopwatch.GetTimestamp() - pingDuration;                }                 var pingTicks = pingDuration * ticksPerSecond / Stopwatch.Frequency;                 // optional: display response-time                // Console.WriteLine("{0:N2} ms", new TimeSpan(pingTicks).TotalMilliseconds);                 var intPart = (long) ntpData[40] << 24 | (long) ntpData[41] << 16 | (long) ntpData[42] << 8 | ntpData[43];                var fractPart = (long) ntpData[44] << 24 | (long) ntpData[45] << 16 | (long) ntpData[46] << 8 | ntpData[47];                var netTicks = intPart * ticksPerSecond + (fractPart * ticksPerSecond >> 32);                 var networkDateTime = new DateTime(ticksTo1900 + netTicks + pingTicks / 2);                 return networkDateTime.ToLocalTime(); // without ToLocalTime() = faster            }            catch            {                // fail                return null;            }        }    }}