ntp Server antwortet nicht

Gast #5426230
Lesenswert?

Hallo,

ich benutze den ESP8266. Wenn ich nun den NTP Server de.pool.ntp.org 
anfrage, bekomme ich keine Antwort "no packet yet". Was mache ich falsch 
oder ist der Server komplett überlastet?
1
// send an NTP request to the time server at the given address
2
unsigned long sendNTPpacket(IPAddress& address)
3
{
4
  Serial.println("sending NTP packet...");
5
  // set all bytes in the buffer to 0
6
  memset(packetBuffer, 0, NTP_PACKET_SIZE);
7
  // Initialize values needed to form NTP request
8
  // (see URL above for details on the packets)
9
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
10
  packetBuffer[1] = 0;     // Stratum, or type of clock
11
  packetBuffer[2] = 6;     // Polling Interval
12
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
13
  // 8 bytes of zero for Root Delay & Root Dispersion
14
  packetBuffer[12]  = 49;
15
  packetBuffer[13]  = 0x4E;
16
  packetBuffer[14]  = 49;
17
  packetBuffer[15]  = 52;
18

19
  // all NTP fields have been given values, now
20
  // you can send a packet requesting a timestamp:
21
  udp.beginPacket(address, 123); //NTP requests are to port 123
22
  udp.write(packetBuffer, NTP_PACKET_SIZE);
23
  udp.endPacket();
24
}
25

26
unsigned long Get_NTP_Time()
27
{
28
  //get a random server from the pool
29
  WiFi.hostByName(ntpServerName, timeServerIP); 
30

31
  sendNTPpacket(timeServerIP); // send an NTP packet to a time server
32
  // wait to see if a reply is available
33
  delay(3000);
34
  
35
  int cb = udp.parsePacket();
36
  if (!cb) {
37
    Serial.println("no packet yet");
38
    return(0);
39
  }
40
  else {
41
    Serial.print("packet received, length=");
42
    Serial.println(cb);
43
    // We've received a packet, read the data from it
44
    udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
45

46
    //the timestamp starts at byte 40 of the received packet and is four bytes,
47
    // or two words, long. First, esxtract the two words:
48

49
    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
50
    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
51
    // combine the four bytes (two words) into a long integer
52
    // this is NTP time (seconds since Jan 1 1900):
53
    unsigned long secsSince1900 = highWord << 16 | lowWord;
54

55
    // now convert NTP time into everyday time:
56
     // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
57
    const unsigned long seventyYears = 2208988800UL;
58
    // subtract seventy years:
59
    unsigned long epoch = secsSince1900 - seventyYears;
60
    // print Unix time:
61
    Serial.print("NTP:");
62
    Serial.println(epoch);
63
    return(epoch); 
64
  }
65
}

[Mod: Code in C-Tags eingeschlossen]
Gast #5426258
Lesenswert?

dost0011 schrieb:
1
>   delay(3000);

Das ist bestenfalls unschön. Pakete sollten verarbeitet werden, wenn sie 
ankommen.
1
>   int cb = udp.parsePacket();

Was macht denn diese Funktion und was gibt sie zurück?

Laß doch mal zum Testen einen lokalen Server laufen und schaue Dir an, 
was im Netzwerk passiert.

de.pool.ntp.org ist übrigens ein einzelner Server, wenn auch immer ein 
anderer.
Moderator Persönliche Seite #5426291
Lesenswert?

dost0011 schrieb:
> sendNTPpacket(timeServerIP); // send an NTP packet to a time server
>   // wait to see if a reply is available
>   delay(3000);
>
>   int cb = udp.parsePacket();

Das ist unschön. UDP ist ein verbindungsloses Protokoll. Du kannst keine 
unmittelbare Antwort erwarten. Diese kommt irgendwann... oder auch gar 
nicht.

Ich mache das beim ESP so, dass ich einmal den Request abfeuere und dann 
in loop() zyklisch frage, ob was über UDP reinkommt.
1
void
2
loop() 
3
{
4
    ... // some other stuff
5
    ntp_poll_time ();                
6
    ... // some other stuff
7
}

wobei:
1
void
2
ntp_poll_time (void)
3
{
4
    int packetsize;
5

6
    packetsize = ntp_udp.parsePacket();
7

8
    if (packetsize)
9
    {
10
        ntp_udp.read(ntp_packet_buffer, packetsize);                   // read packet
11

12
        if (packetsize == NTP_PACKET_SIZE)
13
        {
14
            unsigned long hi = word(ntp_packet_buffer[40], ntp_packet_buffer[41]);
15
            unsigned long lo = word(ntp_packet_buffer[42], ntp_packet_buffer[43]);
16
            unsigned long secsSince1900 = hi << 16 | lo;
17

18
            Serial.print ("TIME ");
19
            Serial.println(secsSince1900);
20
        }
21
        else
22
        {
23
            Serial.println("- wrong packet size");
24
        }
25

26
        Serial.flush ();
27
    }
28
}

Den kompletten Source findestg Du unter 
https://www.mikrocontroller.net/svnbrowser/wordclock24h/ESP8266/ESP-WordClock/
Gast #5426336
Lesenswert?

Also mit dem Delay habe ich rumgespielt, ob es besser oder schlechter 
wird. Spielt keine Rolle, ich kann es auch rausnehmen.
Es kommt einfach keine Antwort zurück - egal, ob ich warte oder nicht.
Kennt ihr das Phänomen?
#5426343
Lesenswert?

Frank M. schrieb:
> Du machst ja auch kein NTP, sondern nur SNTP (Simple ...). Das kann
> keinen Pool nach der Zeit fragen, sondern nur einzelne Server.

Der DNS-Name de.pool.ntp.org liefert bei Übersetzung in eine IP-Adresse 
eine von mehreren Adressen und ist daher in Programmen, die DNS-Namen 
verstehen, üblicherweise direkt nutzbar. Oder hat die ESP-Lib spezielle 
Probleme damit?
Moderator Persönliche Seite #5426354
Lesenswert?

A. K. schrieb:
> Oder hat die ESP-Lib spezielle Probleme damit?

Ich hatte es damals beim ESP8266 mit de.pool.ntp.org und SNTP nicht 
hinbekommen. Ich hatte dann als Server 192.53.103.103 (ntp3.ptb.de) 
probiert. Das ging sofort. Deshalb habe ich es dann auf den Pool im 
Zusammenhang mit SNTP geschoben.

Eben habe ich es aber nochmal (unter Linux, habe gerade keinen ESP 
parat) mit einem SNTP-Client probiert:
1
$ sntp de.pool.ntp.org
2
sntp 4.2.8p11@1.3728-o (1)
3
2018-05-18 13:29:31.010213 (-0100) +0.000558 +/- 0.023336 de.pool.ntp.org 212.18.3.19 s2 no-leap

Das funktioniert. Kann sein, dass es damals ein anderes temporäres 
Problem gab. Ich nehme daher meine Behauptung zurück ;-)

Ich werde es heute abend aber trotzdem nochmal auf dem ESP ausprobieren.
Gast #5426355
Lesenswert?

Ich habe jetzt mal einen festen Server (time.nist.gov NTP server) 
angefragt:

sending NTP packet...
129.6.15.28
no packet yet
sending NTP packet...
129.6.15.28
no packet yet
sending NTP packet...
129.6.15.28
no packet yet
sending NTP packet...
129.6.15.28
no packet yet
sending NTP packet...
129.6.15.28
no packet yet
sending NTP packet...
129.6.15.28
no packet yet
sending NTP packet...
129.6.15.28
no packet yet

Bin ratlos...
Beitrag #5426364 wurde von einem Moderator gelöscht.
Moderator Persönliche Seite #5426394
Lesenswert?

dost0011 schrieb:
> IPAddress timeServerIP(192,53,103,103);
>
> funktioniert auch nicht.

Dies wollte ich Dir gerade auch vorschlagen, hätte ja sein können, dass 
die Namensauflösung aus irgendeinem Grund nicht klappt. Obwohl, Du 
könntest Dir ja mal die IP-Adresse ausgeben lassen, die von 
WiFi.hostByName(ntpServerName, timeServerIP) ermittelt wird.

> Liegt vermutlich nicht an den tausenden Servern
> sondern an meinem Code ;-)

Den habe ich schon mit meinem Code

  https://www.mikrocontroller.net/svnbrowser/wordclock24h/ESP8266/ESP-WordClock/

verglichen. Ich kann keinen größeren Unterschied erkennen, bis auf das 
Delay. Wie gesagt: Schick das Paket einmal ab und führe den Aufruf von 
udp.parsePacket() & Co. zyklich in der Hauptschleife aus, ich hatte das 
oben schon so skizziert.
#5426401
Lesenswert?

Frank M. schrieb:
> Wie gesagt: Führe den Aufruf von udp.parsePacket() & Co. zyklich
> in der Hauptschleife aus, ich hatte das oben schon so skizziert.

Wobei der ESP eigentlich für ereignisorientiertes Arbeiten ausgelegt 
ist, nicht für sequentielles Arbeiten mit Warterei. Also nicht
   Anfrage senden
   warten
   Antwort auswerten
sondern
   Anfrage senden
und unabhängig davon
   Wenn ein UDP Paket eintrifft, dann
      Paket auswerten

Damit habe ich bessere Erfahrungen gemacht. Allerdings war das in LUA.
#5426416
Lesenswert?

Hallo,

nur am Rande: zu den ESP8266 Extensions, die Bestandteil des SDK sind, 
gehört auch die nahezu vollständige Implemetierung der Posix-Time-Lib.
1
#include <ESP8266WiFi.h>
2
#include <time.h>
3

4
setup()
5
{
6
// Start Time service.
7
  configTime(timezone * 3600, 0, "pool.ntp.org", "time.nist.gov");
8
}
9

10
Mit
11
  time_t now = time(nullptr);
12
  struct tm * timeinfo;
13
  timeinfo = localtime(&now);
14
füllt man z.B. die Struktur.
15
 Serial.printf("%02d:%02d:%02d",timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
16
  Serial.println();

Es läuft komplett asyncron im Hintergrund, aktualisiert wird per default 
alle Stunde.

Genaueres kann man sich z.B. hier raussuchen.
https://github.com/esp8266/Arduino/blob/master/tools/sdk/libc/xtensa-lx106-elf/include/time.h

Gruß aus Berlin
Michael
Gast #5426608
Lesenswert?

dost0011 schrieb:

>   packetBuffer[0] = 0b11100011;   // LI, Version, Mode

Das ist falsch. Lies den Standard RFC4330.

LI: Bit 7-6, hier 3 (unsynchronisiert), ok
Version: Bit 2-0, hier 3, auch nicht falsch. Ich würde hier Version 1 
nehmen.
Mode: Bit 5-3, hier 4, und das ist FALSCH.
Du musst hier als Client eine 3 reinschreiben, der Server muss mit 
Mode=4 antworten. Mode=5 ist für Broadcasts.

fchk
Gast #5426615
Lesenswert?

foobar schrieb:
> Nicht dass ne Firewall
> oder fehlendes NAT dir dazwischenfunken ...

Bevor man große Sprünge macht, sollte man sich in kleinen Schritten 
vergewisseren, daß die einfachen Sachen schon mal funktionieren?
Ping wird ausgeführt für de.pool.ntp.org [195.201.19.162] mit 32 Bytes 
Daten:
Antwort von 195.201.19.162: Bytes=32 Zeit=76ms TTL=53 usw.
Beitrag #5426617 wurde von einem Moderator gelöscht.
Moderator Persönliche Seite #5426702
Lesenswert?

fchk schrieb:
> Du musst hier als Client eine 3 reinschreiben, der Server muss mit
> Mode=4 antworten. Mode=5 ist für Broadcasts.

Ich habe das mal unter Linux ausprobiert.

Sowohl
1
   packetBuffer[0] = 0b11100011;  // vom TO verwendet
als auch
1
   packetBuffer[0] = 0b00011011;  // findet man in diversen Quellen
2
                                  // LI = 0, NV = 3, MODE = 3

werden von us.pool.ntp.org, de.pool.ntp.org und ntp3.ptb.de ohne Mucken 
geschluckt. Offenbar interessiert sich keiner für die LI, NV und 
MODE-Bits. Naja, nicht ganz: bei packetBuffer[0] = 0x00 antwortet keiner 
mehr.

Ich habe sonst überhaupt keine Felder im Paket mehr gefüllt, also alles 
bei 0 gelassen (durch memset).

Verwendeter Source:

https://lettier.github.io/posts/2016-04-26-lets-make-a-ntp-client-in-c.html
Gast #5426926
Lesenswert?

Ok, jetzt habe ich folgendes gemacht:
Bei den Arduino Beispiel Sketchen gibt es unter ESP8266Wifi-->NTPClient. 
Diesen Sketch habe ich auf den ESP8266 geladen. Er verbindet sich 
einwandfrei mit dem Internet und dann bekomme ich folgenden Output

sending NTP packet...
no packet yet
sending NTP packet...
packet received, length=48
Seconds since Jan 1 1900 = 3735663005
Unix time = 1526674205
The UTC time is 20:10:05
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet
sending NTP packet...
no packet yet

Das bedeutet, dass es einmal funktioniert hat und dann nicht mehr. Das 
reicht natürlich nicht. Wenn ich einen Reset mache, kann es sein, dass 
er für 10min (dann habe ich abgebrochen) kein einziges Paket empfangen 
habe...

Anpingen kann ich den Server vom Rechner aus.
Was ist da los? Kann mich erinnern, dass das vor einem Jahr sofort und 
zuverlässig funktioniert hat...
Gast #5428709
Lesenswert?

Das Gerät, welches ich bauen möchte, kommt in einer Umgebung zum 
Einsatz, wo es keinen weiteren Rechner gibt. Kann doch nicht sein, dass 
man einen eigenen Zeitserver benötigt, weil die vorhandenen nicht 
antworten. Ich habe doch bestimmt ein ganzes anderes Problem...

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren