Forum: Mikrocontroller und Digitale Elektronik Zeit von ntp-Server abrufen;


von debugger (Gast)


Lesenswert?

Die aktuelle Zeit soll von einem ntp-Server abgerufen werden (über ein 
GPRS-Moduzl, angesteuert von einem MC).
Das klappt auch grundsätzlich, aber der ntp-Server (ptbtime1.ptb.de)
antwortet in ca. der Hälfte der Fälle nicht innerhalb von 3 Sekunden auf
die Anfrage (länger warte ich nicht).

Was habt ihr für Erfahrungen gemacht ?

- Ist es normal, dass nicht immer eine Antwort kommt ?
- Was macht ihr bei fehlender Antwort ? (länger warten, ggf. wie lange
?, nochmal beim gleichen Server probieren, bei einem anderen Server
anfragen, Kombilösung ?)
- welche ntp-Server antworten nach Eurer Erfahrung am schnellsten ?

von oszi40 (Gast)


Lesenswert?

Teste mal pool.ntp.org zum Vergleich

von Dennis S. (bzzzt)


Lesenswert?

Da das ganze über UDP läuft, ist es völlig normal, dass mal keine 
Antwort kommt, weil ein Paket verloren geht. Zumal du GPRS nutzt, gilt 
das umso mehr.
Allerdings sind 50% Paketverlust viel zu viel und liegen nicht an 
ptbtime1.ptb.de: Im Test habe ich 70 ms Latenz und keinen Paketverlust.
Daher: Auf jeden Fall mehrmals probieren.
Probiere mal, was oszi40 meint. Wenn andere NTP-Server genauso schlecht 
antworten, ist deine Netzwerkverbindung schuld. Ist's etwa das 
berüchtigte E-Plus-Netz? ;-) Oder vielleicht deine Anbindung an das 
GPRS-Modul…

Guck dir mal die RTT zu deinen NTP-Servern an. GPRS habe ich so mit 1-2 
Sekunden Latenz in Erinnerung, dann wären deine 3 Sekunden ausreichend, 
da die NTP-Server sofort oder gar nicht antworten.
Wenn der Server einmal nicht antwortet, mehrmals probieren, mit ein 
wenig Verzögerung.
Ein „großer“ NTP-Client auf einem Rechner spricht mit mehreren Servern 
parallel, aber das ist auf einem µC mehr Aufwand als nötig. Dort lohnt 
es nur, falls du die aktuelle Zeit schon ganz schnell nach dem Start des 
Systems wissen musst und deine Server unzuverlässig sind 
(unwahrscheinlich).
Also: Server nacheinander probieren, falls einer gar nicht antwortet.

Mal so aus Interesse: Wie groß ist eigentlich die Varianz bei den 
Antwortzeiten?

von jaeger (Gast)


Lesenswert?

@Dennis : Danke für die Hinweise.
Ja, ich nutze das eplus-Netz. Aber ob es daran liegt, kann ich (noch) 
nicht definitiv sagen.

Bzgl. Deiner Frage zur Varianz bei den Antwortzeiten :
Weiss ich noch nicht, denn ich muss die Auswertung der 48 Bit langen 
Antwort noch implementieren und suche dazu auch noch eine übersichtliche 
Beschreibung des Formates.
Die ntp-Dokus, die ich bisher im Netz gefunden habe, sind extrem 
unübersichtlich und lang.
Die reine Beschreibung des Datenformates der 48 Byte kann doch nicht so 
kompliziert sein ?

von Dennis S. (bzzzt)


Lesenswert?

Du kannst z.B. in den Ethersex-Code gucken, die haben einen NTP-Client 
implementiert (services/ntp/ntp.?), falls du dir nicht RFC 4330 
durchlesen möchtest.
Im Paket ist ein Unix-Zeitstempel enthalten. Diese Zahl in ein 
menschenlesbares Datenformat umzuwandeln, ist eine andere Aufgabe. Dazu 
findest du aber auch genug Code (Ethersex: clock_localtime, wo wir 
gerade dabei sind).

von jaeger (Gast)


Lesenswert?

Dennis S. schrieb:
> Im Paket ist ein Unix-Zeitstempel enthalten.

Welche Bytes das genau sind, kannst Du nicht ev. aus dem Stegreif sagen 
?
Damit wäre für mich der Fall gelöst, weil mir eine Genauigkeit von einer 
Sekunde für die Systemzeit ohne weiteres ausreicht.

von Dennis S. (bzzzt)


Lesenswert?

Aus ntp_fp.h, was mit FreeBSD mitgeliefert wird, vereinfacht:
1
struct ntp_pkt {
2
  uint8_t  li_vn_mode; /* leap indicator, version and mode */
3
  uint8_t  stratum;  /* peer stratum */
4
  uint8_t  ppoll;    /* peer poll interval */
5
  signed char  precision;  /* peer clock precision */
6
  uint32_t  rootdelay;  /* distance to primary clock */
7
  uint32_t  rootdispersion; /* clock dispersion */
8
  uint32_t refid;    /* reference clock ID */
9
  l_fp  reftime;  /* time peer clock was last updated */
10
  l_fp  org;    /* originate time stamp */
11
  l_fp  rec;    /* receive time stamp */
12
  l_fp  xmt;    /* transmit time stamp */
13
  /* No extension included here */
14
};
15
typedef struct {
16
  uint32_t timestamp;
17
  uint32_t fraction;
18
} l_fp;

"timestamp" bezieht sich allerdings auf das Jahr 1900 statt wie bei Unix 
üblich 1970 (also +2208988800 Sekunden, falls du den Unix-Zeitstempel 
willst). Die Zeit vom Server steht in "rec" drin.
Sollten also die Bytes 32 bis 36 sein.

von jaeger (Gast)


Lesenswert?

Danke Dennis, funktioniert !

[Byte 32]  [Byte 33]  [Byte 34]  [Byte 35]
[210]      [193]      [199]      [056]
11010010   11000001   11000111   00111000
1101001011000001      1100011100111000
53953                 51000
53953 * 65536       + 51000  = 3535863808

3535914808  - 2208988800 = 1326926008 = 18.01.2012 23:33:28 Stimmt !

Fazit : Die Bytes 32-35 enthalten tatsächlich den Zeitstempel mit den 
Sekunden seit dem 1.1.1900

von anfaenger (Gast)


Lesenswert?

Ok, die Bytes 32 bis 35 des Blocks (bzw. im gesamten Antwortstring des 
ntp-Servers die Bytes 113 - 116) enthalten die vier Bytes der Sekunden 
seit dem 1.1.1900
Wiess ev. noch jemand spontan, ob und ggf. wo (in welchen Bytes) in dem 
Anwortstring Angaben zur Zeitzone enthalten sind ?
Beim letzten Test wurde die Zeit von ptbtime1.ptb.de in MEZ und nicht 
UTC (bzw. GMT) zurückgegeben.

von Johannes G. (gutenberg)


Lesenswert?

Ich dachte es wird immer UTC übertragen. Die Interpretation (sezten der 
richtigen Zeitzone) ist Aufgabe von deinem lokalen System.

von debugger (Gast)


Angehängte Dateien:

Lesenswert?

Johannes G. schrieb:
> Ich dachte es wird immer UTC übertragen. Die Interpretation (sezten der
> richtigen Zeitzone) ist Aufgabe von deinem lokalen System.

Das dachte ich auch. Der ntp-Server schickt die Zeit aber eindeutig mit 
der  MEZ-Zeitzone (habe das gerade nochmal überprüft).
Liegt es ev. an der Anforderung oder gibt es in der Antwort eine 
Sequenz, in der die Zeitzone angegeben ist. Im Anhang poste ich mal die 
Anfrage, die Antwort des ntp-Servers und die Umrechung in die Unix-Zeit.
Vielleicht hat ja jemand noch eine Idee, bevor ich die Spezifikationen 
wälzen muss.

von Dennis S. (bzzzt)


Lesenswert?

Also in RFC1305 ist beschrieben, dass die Daten in UTC vorliegen. Davon 
kannst du ausgehen.

von anfaenger (Gast)


Lesenswert?

Der vom ntp-Server (ptbtime1.ptb.de) zurückgelieferte Zeitwert gibt mir 
immer noch Rätsel auf :

Auf meine Anforderung am 09.05.2012 um 10:06:17 (MESZ) bekomme ich in 
der Antwort (Byte[absolut/Antwortanteil relativ]) :

Byte[113/32]=211 Byte[114/33]=84 Byte[115/34]=163 Byte[116/35]=249

das ergibt eine ntp-Zeit von 3545539577

Die Korrektur (1.1.1900 - 1.1.1970) -2208988800 ergibt eine ntp_unixzeit 
von 1336550777

Laut http://www.aritso.net/aritso-tools/timestampconverter/ entspricht 
die Unixzeit 133655077 für UTC0 der Zeit 09.05.2012 um 09:06:17 Uhr.

Aber tatsächlich ist UTC=(MESZ-2), es müsste also 08:06:17 Uhr 
zurückgeliefert werden, wenn der ntp-Server die UTC-Zeit überträgt ?

von (prx) A. K. (prx)


Angehängte Dateien:

Lesenswert?

Grad mit Linux ntpdate ausprobiert. Nicht mit PTB, aber dieser Server 
jedenfalls liefert UTC, wie es sich gehört.

von anfaenger (Gast)


Lesenswert?

Stimmt dann ev. der Korrekturwert von -2208988800 zwischen 1.1.1900 und 
1.1.1970 nicht, sondern müsste der noch -3600 verkleinert werden ?

von anfaenger (Gast)


Lesenswert?

Danke für den Check, was für einen Server hast Du verwendet ?
Ich baue die Verbindung übver GPRS und eplus auf, das dauert manchmal 
auch etwas länger :-)

von (prx) A. K. (prx)


Lesenswert?

anfaenger schrieb:

> Danke für den Check, was für einen Server hast Du verwendet ?

Einen netzinternen. Der eigentlich Punkt ist aber ein anderer: Im NTP 
existiert wie erkennbar kein Feld, welches eine Zeitzone des Servers 
oder eine Differenz zu UTC definiert. Da der Client also nicht wissen 
kann, in welcher Zeitzone der Server sitzt, kann NTP über 
Zeitzonengrenzen hinweg nur funktionieren, wenn alle angegebenen Zeiten 
UTC sind.

von anfaenger (Gast)


Lesenswert?

Der Anfragestring ist ja 48 Zeichen lang. Da ich nicht die Bedeutung 
aller Bytes kenne, bin ich mir auch nicht sicher, ob da irgendwo Platz 
für Angaben zur gewünschten Zeitzone ist.
Ich verwende wohl den Basis-Anfragestring, der wird aber offensichtlich 
akzeptiert.

von Sascha W. (sascha-w)


Lesenswert?

Hallo,

also ich sende immer das ...
1
NTP_Request_dx:  .db  0xd9,0x00,0x0a,0xfa,0x00,0x00,0x00,0x00
2
        .db  0x00,0x01,0x04,0x00,0x00,0x00,0x00,0x00
3
        .db  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
4
        .db  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
5
        .db  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
6
        .db  0xc7,0xd6,0xac,0x72,0x08,0x00,0x00,0x00

subtrahiere wie du 2208988800
und addiere für MEZ 3600 und für MESZ 7200

als Server kommt 113.28.36.124 zum Einsatz

Sascha

von (prx) A. K. (prx)


Lesenswert?

anfaenger schrieb:

> Der Anfragestring ist ja 48 Zeichen lang. Da ich nicht die Bedeutung
> aller Bytes kenne, bin ich mir auch nicht sicher, ob da irgendwo Platz
> für Angaben zur gewünschten Zeitzone ist.

Die Formate von Request- und Reply-Paket sind gleich. Der einzige 
Unterschied liegt im Inhalt der Flags Bitmap.

NTP funktioniert innerhalb eines LANs auch per Broadcast. Eine Station 
kann dann die Uhrzeit einfach vom Netz fischen ohne explizit anzufragen.

von anfaenger (Gast)


Lesenswert?

Zur Info (aus diesem Thread : 
Beitrag "Zeit und Datum aus Unix-Zeit, schlanker Code gesucht;")

Echt klasse !
Damit hat sich auch das NTP-Problem aus diesem Thread erledigt :
Beitrag "Zeit von ntp-Server abrufen;"

Für die Unix-Zeit 1336550777 liefert der Code von Bernhard den korrekten
UTC Datum/Zeit-Wert 20120509 08:06:17 (JJJJMMTT HH:MM:SS)

Ich war schon ziemlich genervt, weil die Zeiten eines ntp-Servers ja
prinzipiell im UTC-Format übermittelt werden sollten, mir dieser Link
http://www.aritso.net/aritso-tools/timestampconverter/ aus dem
Unix-Zeitwert aber immer UTC+1 (=MEZ) berechnet hat (auch wenn UTC
vorgegeben war)
Das Ergebnis lautet z.B. für die oben verwendete Unix-Zeit
"Der Timestamp 1336550777 entspricht dem 09.05.2012 um 09:06:17 Uhr.
(gilt für UTC 0)"

THX !

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.