Obtain accurate Time from NIST Internet Time Servers Based on Time Protocol, nistservers
Time Protocol (RFC-868) is a very simple application layer Protocol: it returns a 32-bit binary number that describes the number of seconds from January 1, 1900 00:00:00 to the present, the server listens for Time Protocol requests on port 37 of TCP. This function converts the server return value to the local time.
Previously, I did not know that there was a ready-made IPAddress. NetworkToHostOrder function. Therefore, I wrote a ReverseBytes function to convert byte arrays from Big-endian to Little-endian. This function may also be useful in other places, so the flexibility will be preserved.
1 private const int BUFSIZE = 4; // the size of the character array 2 private const int PORT = 37; // server PORT number 3 private const int TIMEOUT = 3000; // timeout (MS) 4 private const int MAXTRIES = 3; // The number of attempts to receive data 5 6 /// <summary> 7 // obtain the exact Time from NIST Internet Time Servers. 8 /// </summary> 9 /// <param name = "dateTime"> returns an accurate local time </param> 10 /// <param name = "timeServer"> Server LIST </param> 11 /// <returns> If the query time fails, false is returned, otherwise, true </returns> 12 public static bool GetDateTimeFromTimeServer (out DateTime now, string timeServers = "time.nist.gov") 13 {14 Socket socket = new Socket (AddressFamily. interNetwork, SocketType. stream, ProtocolType. tcp); 15 // set the timeout value for obtaining 16 socket. setSocketOption (So CketOptionLevel. socket, SocketOptionName. receiveTimeout, TIMEOUT); 17 18 byte [] rcvBytes = new byte [BUFSIZE]; // The byte array of received data 19 int tries = 0; // record attempts 20 bool received ED = false; // whether the reception is successful 21 int totalBytesRcvd = 0; // The total number of received bytes 22 int bytesRcvd = 0; // The number of bytes received this time 23 do24 {25 try26 {27 socket. connect (Dns. getHostEntry (timeServers ). addressList, PORT); 28 while (bytesRcvd = socket. receive (rcvBytes, totalBytesRcvd, B UFSIZE-totalBytesRcvd, SocketFlags. none)> 0) 29 {30 totalBytesRcvd + = bytesRcvd; 31} 32 bytes ED = true; 33} 34 catch (SocketException) 35 {36 // timeout or other Socket errors, increase the number of parameters 37 tries ++; 38} 39} while ((! Received) & (tries <MAXTRIES); 40 socket. close (); 41 42 if (encoded ed) 43 {44 // convert the byte array from Big-endian to Little-endian45 // ReverseBytes (ref rcvBytes, 0, 4 ); 46 // UInt32 seconds = BitConverter. toUInt32 (rcvBytes, 0); 47 UInt32 seconds = BitConverter. toUInt32 (rcvBytes, 0); 48 if (BitConverter. isLittleEndian) 49 {50 seconds = (UInt32) IPAddress. networkToHostOrder (int) seconds); 51} 52 // Add the obtained number of seconds on the January 1, 1900 00:00:00 date and convert it to the current local time zone 53 now = new DateTime (1900, 1, 1, 1, 0, 0, 0, DateTimeKind. utc ). addSeconds (seconds ). toLocalTime (); 54 return true; 55} 56 else57 {58 now = DateTime. now; 59 return false; 60} 61} 62 63 // <summary> 64 // flip byte array byte order 65 /// </summary> 66 // <param name = "bytes "> byte array to be flipped </param> 67 // <param name =" start "> specify the conversion start position </param> 68 // <param name =" len "> length to be flipped </param> 69 private static void ReverseBytes (ref byte [] bytes, int start, int len) 70 {71 if (start <0) | (start> bytes. length-1) | (len> bytes. length) 72 {73 throw new ArgumentOutOfRangeException (); 74} 75 76 int end = start + len-1; 77 if (end> bytes. length) 78 {79 throw new ArgumentOutOfRangeException (); 80} 81 82 byte tmp; 83 for (int I = 0, index = start; index <start + len/2; index ++, I ++) 84 {85 tmp = bytes [end-I]; 86 bytes [end-I] = bytes [index]; 87 bytes [index] = tmp; 88} 89}
The Code has not been strictly tested. If there is any error, please point it out. Thank you!
References
[1] Chen Xiangning, Wang Xiaoyang, Chen Tingting, Zhang Zhe. Third edition of Windows network and communication program design [M]. People's post and telecommunications press,-28.
[2] D. Makofske, M. Donahoo, K. Calvert. TCPIP Sockets in C # Practical Guide for Programmers [M]. Morgan Kaufmann.2004.
NIST Internet Time Servers. http://tf.nist.gov/tf-cgi/servers.cgi.