通过NTP协议进行时间同步

  1        //available ntp servers

  2        /*

  3         *美国apple: time.asia.apple.com 

  4         *美国 Microsoft公司 131.107.1.10

  5         *新加坡 203.117.180.36

  6         *美国 clock.via.net 

  7         *上海交通大学 ntp.sjtu.edu.cn

  8         *美国 马萨诸塞州大波士顿区麻省理工学院 18.145.0.30 

  9         *德国 柏林工业大学130.149.17.21

 10         *美国 宾夕法尼亚州立大学 128.118.46.3

 11         *日本 福冈大学 133.100.9.2

 12         *澳大利亚 堪培拉大学137.92.140.80

 13         */

 14         /// <summary>

 15         /// get current date time from net work.

 16         /// </summary>

 17         /// <returns></returns>

 18         private DateTime GetLocalDateTime(int timeZone)

 19         {

 20             DateTime? utcDateTime = null;

 21             //set ntp servers.

 22             string[] ntpServer = 

 23             { 

 24               "time.asia.apple.com",

 25               "ntp.sjtu.edu.cn",

 26               "131.107.1.10 ",

 27               "203.117.180.36",

 28               "130.149.17.21",

 29               "133.100.9.2",

 30               "137.92.140.80"

 31             };

 32             //get utc from ntp server.

 33             for (int ntpServerIndex = 0; ntpServerIndex < ntpServer.Length; ntpServerIndex++)

 34             {

 35                 try

 36                 {

 37                     utcDateTime = NTPHelper.GetUTCDate(ntpServer[ntpServerIndex]);

 38                     //if success to get utc,Jump out the loop

 39                     break;

 40                 }

 41                 catch

 42                 {

 43                     //if throw exception,get utc from another ntp server.

 44                     continue;

 45                 }

 46             }

 47             if (utcDateTime != null)

 48             {

 49                 return utcDateTime.Value.AddHours(timeZone);

 50             }

 51             else

 52             {

 53                 throw new Exception("can't get utc");

 54             }

 55         }

 56 

 57     public class NTPHelper

 58     {

 59         public static DateTime GetUTCDate(string ntpServer)

 60         {

 61             // NTP message size - 16 bytes of the digest (RFC 2030)

 62             var ntpData = new byte[48];

 63             //Setting the Leap Indicator, Version Number and Mode values

 64             //LI = 0 (no warning), VN = 3 (IPv4 only), Mode = 3 (Client Mode)

 65             ntpData[0] = 0x1B;

 66             try

 67             {

 68                 var addresses = Dns.GetHostEntry(ntpServer).AddressList;

 69                 //The UDP port number assigned to NTP is 123

 70                 var ipEndPoint = new IPEndPoint(addresses[0], 123);

 71                 //NTP uses UDP

 72                 var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

 73 

 74                 socket.Connect(ipEndPoint);

 75                 //Stops code hang if NTP is blocked

 76                 socket.ReceiveTimeout = 3000;

 77 

 78                 socket.Send(ntpData);

 79                 socket.Receive(ntpData);

 80                 socket.Close();

 81                 //Offset to get to the "Transmit Timestamp" field (time at which the reply 

 82                 //departed the server for the client, in 64-bit timestamp format."

 83                 const byte serverReplyTime = 40;

 84                 //Get the seconds part

 85                 ulong intPart = BitConverter.ToUInt32(ntpData, serverReplyTime);

 86                 //Get the seconds fraction

 87                 ulong fractPart = BitConverter.ToUInt32(ntpData, serverReplyTime + 4);

 88                 //Convert From big-endian to little-endian

 89                 intPart = SwapEndianness(intPart);

 90                 fractPart = SwapEndianness(fractPart);

 91 

 92                 var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);

 93                 //**UTC** time

 94                 var networkDateTime = (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)).AddMilliseconds((long)milliseconds);

 95 

 96                 return networkDateTime;

 97             }

 98             catch(Exception ex)

 99             {

100                 throw ex;

101             }

102         }

103 

104         // stackoverflow.com/a/3294698/162671

105         static uint SwapEndianness(ulong x)

106         {

107             return (uint)(((x & 0x000000ff) << 24) +

108                            ((x & 0x0000ff00) << 8) +

109                            ((x & 0x00ff0000) >> 8) +

110                            ((x & 0xff000000) >> 24));

111         }

112     }

 

你可能感兴趣的:(时间同步)