Zeitserver mit C# abfragen 👍 👎

Im Folgenden möchte ich drei Möglichkeiten vorstellen, wie man mit C# über ein Netzwerk eine Zeitangabe abrufen kann. Es gilt zu beachten, dass es sich um sehr reduzierte Beispiele handelt und beispielsweise keine umfassende Fehlerbehandlung berücksichtigt wird. Wir verwenden standardmäßig jeweils einen Server des NIST.

Time Protocol

Beim Time Protocol handelt es sich um ein sehr einfaches (und etwas betagtes) Protokoll. Der Dienst steht für gewöhnlich unter Port 37 zur Verfügung. Details zum Protokoll können in RFC 868 nachgelesen werden.

Methode zur Zeitabfrage per Time Protocol
010203040506070809101112131415161718
public static DateTime GetTime(string host = "time.nist.gov", int port = 37) {    using(TcpClient client = new TcpClient(host, port)) {        using(NetworkStream networkStream = client.GetStream()) {            // Antwort lesen            byte[] timeBuffer = new byte[4];            networkStream.Read(timeBuffer, 0, timeBuffer.Length);
// Byte-Reihenfolge ggf. umkehren if(BitConverter.IsLittleEndian) { Array.Reverse(timeBuffer); }
return (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)) .AddSeconds(BitConverter.ToUInt32(timeBuffer, 0)) .ToLocalTime(); } }}

Daytime Protocol

Beim Daytime Protocol verhält es sich ähnlich, ist jedoch textbasiert. Der Dienst steht für gewöhnlich unter Port 13 zur Verfügung. Details zum Rückgabeformat können in RFC 867 und der Dienstbeschreibung des NIST nachgelesen werden – wir werden uns auf den minimalen Part (Datum und Uhrzeit) beschränken.

Methode zur Zeitabfrage per Daytime Protocol
010203040506070809101112131415161718
public static DateTime GetDaytime(string host = "time.nist.gov", int port = 13) {    using(TcpClient client = new TcpClient(host, port)) {        using(StreamReader streamReader = new StreamReader(client.GetStream())) {            // Antwort lesen und auftrennen            string[] response = streamReader.ReadToEnd().Split(' ');
// Datum und Uhrzeit ermitteln int[] date = Array.ConvertAll(response[1].Split('-'), Int32.Parse); int[] time = Array.ConvertAll(response[2].Split(':'), Int32.Parse);
return new DateTime( CultureInfo.CurrentCulture.Calendar.ToFourDigitYear(date[0]), date[1], date[2], time[0], time[1], time[2], DateTimeKind.Utc ).ToLocalTime(); } }}

Network Time Protocol (NTP)

Beim Network Time Protocol handelt es sich um einen weit verbreiteten Standard zur Zeitsynchronisierung in Computernetzwerken über Port 123. Details zum Protokoll können in RFC 5905 nachgelesen werden – wir werden uns wieder auf einen minimalen Teil beschränken. Als Server bietet sich hier natürlich auch die PTB an.

Methode zur Zeitabfrage per NTP
010203040506070809101112131415161718192021222324252627282930313233343536
public static DateTime GetNetworkTime(string host = "time.nist.gov", int port = 123) {    using(UdpClient client = new UdpClient()) {        client.Connect(host, port);
// Anfrage senden const byte header = ( (0 << 6) // LI = 0 (keine Warnung; zur Verdeutlichung ausformuliert) | (4 << 3) // VN = 4 (Version) | (3 << 0) // Mode = 3 (Client) ); // 00_100_011
byte[] request = new byte[48];
request[0] = header;
client.Send(request, request.Length);
// Antwort lesen IPEndPoint endPoint = new IPEndPoint(IPAddress.Any, 0); byte[] response = client.Receive(ref endPoint);
// Daten ab Offset aus ggf. umgekehrter Byte-Reihenfolge ermitteln const int offset = 40;
if(BitConverter.IsLittleEndian) { Array.Reverse(response, offset, 4); Array.Reverse(response, (offset + 4), 4); }
ulong integerPart = BitConverter.ToUInt32(response, offset); ulong fractionalPart = BitConverter.ToUInt32(response, (offset + 4));
return (new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc)) .AddMilliseconds((integerPart * 1000) + ((fractionalPart * 1000) / UInt32.MaxValue)) .ToLocalTime(); }}
Insbesondere bei diesem letzten Beispiel möchte ich noch einmal explizit darauf hinweisen, dass es sich um eine sehr reduzierte Implementierung handelt. Die Rückgabe erfolgt bei allen Beispielen jeweils bereits in lokaler Zeit.


Projektverweise

Kategorien / Archiv  |  Übersicht RSS-Feed

Schlagworte

Suche