1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
// **********************************************
// Dies ist eines der 322 Rezepte aus dem
// C# 2005 Premium Codebook.
// Das Snippet wurde vom Autor mit freundlicher
// Genehmigung von Addison Wesley
// bei dotnet-snippets.de veröffentlicht.
// **********************************************
using System;
using System.Text;
using System.Net.Sockets;
/// <summary>
/// Fragt das aktuelle Datum (inklusive Zeit) bei einem NIST-Server ab
/// </summary>
/// <returns>Gibt das abgefragte Datum zurück</returns>
public static System.DateTime GetNISTTime()
{
// Variable für Fehlermeldungen
string errors = null;
// Array für die abzufragenden Server
string[] servers = {"time-a.nist.gov", "time-b.nist.gov",
"time.nist.gov", "utcnist.colorado.edu", "nist1.datum.com"};
// Schleife, in der die Server abgefragt werden, bis das Ergebnis
// in Ordnung ist
for (int i = 0; i < servers.Length; i++)
{
TcpClient tcpClient = null;
try
{
// TcpClient erzeugen und den Empfangs-Timeout auf eine Sekunde
// setzen
tcpClient = new TcpClient();
tcpClient.ReceiveTimeout = 1000;
// Versuch zum aktuellen Server eine Verbindung aufzubauen
tcpClient.Connect(servers[i], 13);
// Den NetworkStream referenzieren
NetworkStream networkStream = tcpClient.GetStream();
string result = null;
if (networkStream.CanWrite && networkStream.CanRead)
{
// Das Ergebnis empfangen und in ASCII konvertieren
byte[] bytes = new byte[tcpClient.ReceiveBufferSize];
try
{
networkStream.Read(bytes, 0,
(int)tcpClient.ReceiveBufferSize);
result = Encoding.ASCII.GetString(bytes);
}
catch (Exception ex)
{
// Fehler dokumentieren
if (errors != null) errors += "\r\n";
errors += "Fehler bei der Abfrage von '" + servers[i] +
": " + ex.Message;
}
}
if (result != null)
{
// Das Ergebnis, das die Form JJJJJ YR-MO-DA HH:MM:SS TT L H msADV
// UTC(NIST) OTM besitzt, in einzelne Token aufsplitten
string[] token = result.Split(' ');
// Anzahl der Token überprüfen
if (token.Length >= 6)
{
// Den Health-Status auslesen und überprüfen
string health = token[5];
if (health == "0")
{
// Alles ok: Datums- und Zeitangaben auslesen
string[] dates = token[1].Split('-');
string[] times = token[2].Split(':');
// DateTime-Instanz mit diesen Daten erzeugen
System.DateTime utcDate =
new System.DateTime(Int32.Parse(dates[0]) + 2000,
Int32.Parse(dates[1]), Int32.Parse(dates[2]),
Int32.Parse(times[0]), Int32.Parse(times[1]),
Int32.Parse(times[2]));
// Lokale Zeit berechnen und zurückgeben
return TimeZone.CurrentTimeZone.ToLocalTime(utcDate);
}
else
{
// Fehler dokumentieren
if (errors != null) errors += "\r\n";
errors += "Fehler bei der Abfrage von '" + servers[i] +
": Der Health-Status ist " + health;
}
}
else
{
// Fehler dokumentieren
if (errors != null) errors += "\r\n";
errors += "Fehler bei der Abfrage von '" + servers[i] +
": Die Anzahl der Token ist kleiner als 6";
}
}
}
catch (Exception ex)
{
// Fehler dokumentieren
if (errors != null) errors += "\r\n";
errors += "Fehler bei der Abfrage von '" +
servers[i] + ": " + ex.Message;
}
finally
{
try
{
// TcpClient schließen
tcpClient.Close();
}
catch { }
}
}
// Wenn die Methode hier ankommt, sind bei allen Abfragen
// Fehler aufgetreten, also eine Ausnahme werfen
throw new Exception(errors);
}
|