Basic SNTP client UdpClient
suggest changeSee RFC 2030 for details on the SNTP protocol.
using System; using System.Globalization; using System.Linq; using System.Net; using System.Net.Sockets; class SntpClient { const int SntpPort = 123; static DateTime BaseDate = new DateTime(1900, 1, 1); static void Main(string[] args) { if(args.Length == 0) { Console.WriteLine("Simple SNTP client"); Console.WriteLine(); Console.WriteLine("Usage: sntpclient <sntp server url> [<local timezone>]"); Console.WriteLine(); Console.WriteLine("<local timezone>: a number between -12 and 12 as hours from UTC"); Console.WriteLine("(append .5 for an extra half an hour)"); return; } double localTimeZoneInHours = 0; if(args.Length > 1) localTimeZoneInHours = double.Parse(args[1], CultureInfo.InvariantCulture); var udpClient = new UdpClient(); udpClient.Client.ReceiveTimeout = 5000; var sntpRequest = new byte[48]; sntpRequest[0] = 0x23; //LI=0 (no warning), VN=4, Mode=3 (client) udpClient.Send( dgram: sntpRequest, bytes: sntpRequest.Length, hostname: args[0], port: SntpPort); byte[] sntpResponse; try { IPEndPoint remoteEndpoint = null; sntpResponse = udpClient.Receive(ref remoteEndpoint); } catch(SocketException) { Console.WriteLine("*** No response received from the server"); return; } uint numberOfSeconds; if(BitConverter.IsLittleEndian) numberOfSeconds = BitConverter.ToUInt32( sntpResponse.Skip(40).Take(4).Reverse().ToArray() ,0); else numberOfSeconds = BitConverter.ToUInt32(sntpResponse, 40); var date = BaseDate.AddSeconds(numberOfSeconds).AddHours(localTimeZoneInHours); Console.WriteLine( $"Current date in server: {date:yyyy-MM-dd HH:mm:ss} UTC{localTimeZoneInHours:+0.#;-0.#;.}"); } }
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents