Forum: Mikrocontroller und Digitale Elektronik ESP8266: wie ganz abgeschalteten Client erkennen?


von Bot N. (botnec)


Lesenswert?

Hallo,
ich betreibe zwei ESP8266 als WiFiServer und WiFiClient. Normalerweise
funktioniert alles wie es soll.

Es taucht allerdings ein Problem auf, wenn der Client sich nicht
"normal" abmeldet, sondern z.B. einfach die Stromversorgung
abgeschaltet wird und er so auf dem Netzwerk fällt. In diesem
Fall erkennt der Server nicht, dass die Verbindung nicht mehr zum
Client besteht. Er bleibt deswegen für einen neuen Clients gesperrt
bis nach ca. 15 bis 20 Minuten wohl eine anderer Mechanismus
die Verbindung beendet.

Meine Anwendung benötigt, dass der Client sich normalerweise nicht 
disconnected , sondern solange mit dem Server verbunden bleibt und
von diesem mit Daten versorgt wird bis der Client sich "normal"
abmeldet.

Ich benutze client.flush und client.disconnected() beim Server,
das scheint aber für diesen Fall nicht auszureichen. Meine
umfangreichen Recherchen im WEB habe eigentlich keine Lösung des
Problems gefunden.

Kann mir hier bitte jemand weiterhelfen?

Danke

: Bearbeitet durch User
von Jan (dunno)


Lesenswert?

Üblicherweise kann man einstellen, wie lange ein Server eine 
Client-Verbindung aufrechterhält auch ohne dass dieser etwas schickt 
(timeout) - den kürzer setzen und dann ggfs keepalive einbauen.

von Bot N. (botnec)


Lesenswert?

Jan schrieb:
> Üblicherweise kann man einstellen, wie lange ein Server eine
> Client-Verbindung aufrechterhält auch ohne dass dieser etwas schickt
> (timeout) - den kürzer setzen und dann ggfs keepalive einbauen.

Wie macht man das bitte ?

von Frank K. (fchk)


Lesenswert?

Sende periodisch (z.B. alle 15s) Pakete, und wenn Du auf drei oder 4 
keine Antwort bekommen hast, dann ist die Gegenstelle weg.

Pakete können entweder ICMP/Echo request/response (ping) sein, oder 
irgendwelche Anfragen im verwendeten Kommunikationsprotokoll.

fchk

von Hannes J. (Firma: _⌨_) (pnuebergang)


Lesenswert?

Ich kenne die Server-Seite von ESP8266 APIs nicht. Nebenbei, du verrätst 
uns nicht mal welche Umgebung (API, Sprache, Toolkits, ...) geschweige 
denn welche Protokolle oberhalb Layer 2 du verwendest. Aus "WiFi" kann 
man erraten was L1 (Phys) und L2 (MAC) sind, aber der Rest fehlt.

Daher nur ein paar generelle Hinweise.

Normalerweise baut man einen Server "concurrent" auf. D.h. der Server 
kann mehrere Verbindungen zu Clients gleichzeitig abhandeln. Dabei fällt 
ein hängender Client nicht so ins Gewicht und kann irgendwann von irgend 
einem Timeout abgeräumt werden. Nur bei ganz einfachen Diensten und wenn 
es eben nicht auf allzeitige Verfügbarkeit des Servers ankommt baut man 
einen iterativen Server. Aber genau das scheinst du gemacht zu haben.

D.h. an dem Punkt würde ich mal die gesamte Architektur überdenken und 
tief in das verwendete API und die angebotenen Mechanismen des Systems 
schauen um einen concurrent Server zu bauen.

Die bereits erwähnten Timeouts musst du sowieso haben, egal ob iterativ 
oder concurrent. Bei concurrent hast du nur mehr Luft und kannst dem 
Client mehr Zeit für z.B. Wiederholungen geben wenn die Verbindung 
gestört ist.

von Bot N. (botnec)


Lesenswert?

Hannes J. schrieb:
> Aus "WiFi" kann
> man erraten was L1 (Phys) und L2 (MAC) sind, aber der Rest fehlt.

Ich habe kein Problem damit zuzugeben, dass ich speziell davon
keine Ahnung habe. Ich verwende die landläufigen Libraries in diesem
Fall für den ESP8266 in C und benutze Platformio. Ich bitte also um
Nachsicht bei meiner Frage.

Die Librarybeschreibungen die ich dazu gefunden haben sagen für mich
nichts darüber aus, was hinter den Funktionen im Detail steckt und wie
man eventuelle Probleme der beschriebenen Art verhindert oder umgeht.
Oder wie und wo man Timeouts anwendet oder benutzt.
Meine Anwendung basiert auf allseits verfügbare WiFi Server/Client
Examples aus dem WEB.

: Bearbeitet durch User
von Rahul D. (rahul)


Lesenswert?

Bot N. schrieb:
> Die Librarybeschreibungen die ich dazu gefunden haben sagen für mich
> nichts darüber aus, was hinter den Funktionen im Detail steckt und wie
> man eventuelle Probleme der beschriebenen Art verhindert oder umgeht.
> Oder wie und wo man Timeouts anwendet oder benutzt.
> Meine Anwendung basiert auf allseits verfügbare WiFi Server/Client
> Examples aus dem WEB.

Wenn man wüsste, welche Library du verwendest (Link?!), gäbe es vielcht 
jemand, der die kennt oder sachkundiger als du bist.

von Bot N. (botnec)


Lesenswert?


: Bearbeitet durch User
von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Die Doku von Arduino.cc kannst du schon mal knicken, weil Arduino nichts 
mit dem ESP8266 am Hut hat.

Der Arduino Core für den ESP8266 basiert auf auf den NONOS SDK von 
Espressif und stammt weder von Espressif noch von Arduino. Die Autoren 
haben sich bemüht, das Verhalten der originalen Arduino Variante so weit 
es geht nachzuahmen. Das SDK von Espressif verwendet wiederum lwIP.

Relevant ist also nur das bisschen Doku auf
https://arduino-esp8266.readthedocs.io und
https://github.com/espressif/ESP8266_NONOS_SDK und
https://savannah.nongnu.org/projects/lwip/

Oder besser: Quelltexte untersuchen.

Frank K. schrieb:
> Sende periodisch (z.B. alle 15s) Pakete, und wenn Du auf drei oder 4
> keine Antwort bekommen hast, dann ist die Gegenstelle weg.

So würde ich es auch empfehlen. Da die Gegenseite ihr Verschwinden nicht 
signalisiert, bleibt die Verbindung für immer bestehen. Es sei denn, 
deine Software auf dem ESP8266 trennt sie aktiv.

: Bearbeitet durch User
von Bot N. (botnec)


Lesenswert?

Vielen Dank für die Klarstellung. Wusste ich nicht, habe einfach ein
Beispiel übernommen und mir weiter keine Gedanken gemacht, nachdem
eigentlich alles soweit gut gelaufen ist.

Der Lösungsansatz von Frank K. hat bei mir nicht geklappt, da der Server
unentwegt sendet auch ohne Client.

Habe jetzt noch einen weiteren Ansatz mit Ping gefunden. Werde das
mal versuchen.

von Hmmm (hmmm)


Lesenswert?

Bot N. schrieb:
> Der Lösungsansatz von Frank K. hat bei mir nicht geklappt, da der Server
> unentwegt sendet auch ohne Client.

Dann hast Du das Konzept nicht verstanden.

Client UND Server müssen regelmässig Daten senden. Wenn eine Seite nach 
x Sekunden immer noch nichts zu erzählen hat, wird ein Keepalive-Paket 
geschickt, das nur bescheid sagt, dass der Absender noch da ist.

Wenn x Sekunden lang nichts von der Gegenstelle kam, wird im Fall des 
Servers der Client abgeworfen, im Fall des Clients wird die Verbindung 
zum Server getrennt und neu aufgebaut.

Bot N. schrieb:
> Habe jetzt noch einen weiteren Ansatz mit Ping gefunden.

Solange Du Einfluss auf das Protokoll hast, ist sowas Murks. Dass ICMP 
durchgeht, heisst noch lange nicht, dass TCP auch durchgeht und die 
Verbindung noch lebt.

: Bearbeitet durch User
von Bot N. (botnec)


Lesenswert?

Hmmm schrieb:
> Dann hast Du das Konzept nicht verstanden.

> Client UND Server müssen regelmässig Daten senden. Wenn eine Seite nach
> x Sekunden immer noch nichts zu erzählen hat, wird ein Keepalive-Paket
> geschickt, das nur bescheid sagt, dass der Absender noch da ist.

Ich bin lernwillig!

Weitere dumme Frage: Auf welcher Ebene muss denn das passieren? Macht
das das Protokoll selber oder muss ich das auf meiner Datenebene machen?

Meine Erfahrung ist, dass die TCPServer TCPClient Verbindung 
grundsätzlich
solange hält bis der Client sich ordentlich abmeldet oder (aus
irgend einem Grunde bei mir nach ca. 15 bis 20 Minuten) der Server die
Verbindung abbricht wenn der Client nicht mehr im Netzwerk ist.

Wenn ich eine TCP Verbindung als TCP-Client mit einem PC Tool (z.B
Hercules_3_2-8) zu einem TCP Server aufbaue, sehe ich keine Möglichkeit
wie ich das oben bewerkstelligen soll. Die Verbindung bleibt aber 
dennoch
beliebig lange erhalten bis ich selber die Verbindung schließe.Das
Tool merkt auch nicht (jedenfalls nicht gleich) wenn der Client weg ist.

: Bearbeitet durch User
von Hmmm (hmmm)


Lesenswert?

Bot N. schrieb:
> Weitere dumme Frage: Auf welcher Ebene muss denn das passieren? Macht
> das das Protokoll selber oder muss ich das auf meiner Datenebene machen?

Das musst Du selbst machen. Bis das OS aufgibt, kann es deutlich länger 
dauern.

Bot N. schrieb:
> Wenn ich eine TCP Verbindung als TCP-Client mit einem PC Tool (z.B
> Hercules_3_2-8) zu einem TCP Server aufbaue, sehe ich keine Möglichkeit
> wie ich das oben bewerkstelligen soll.

Vielleicht solltest Du erstmal beschreiben, was Du da genau tust. Bisher 
war von "Deiner Anwendung" die Rede, da gehe ich davon aus, dass Du die 
volle Kontrolle über das Protokoll und den Code auf beiden Seiten hast.

von Bot N. (botnec)


Lesenswert?

Hmmm schrieb:
> Vielleicht solltest Du erstmal beschreiben, was Du da genau tust. Bisher
> war von "Deiner Anwendung" die Rede, da gehe ich davon aus, dass Du die
> volle Kontrolle über das Protokoll und den Code auf beiden Seiten hast.

Habe die volle Kontrolle nur über den Server , aber nicht über
alle Clients!

Im Prinzip habe ich eine Server (ESP8266)der Daten von Sensoren
sammelt und diese an einen Client weitergeben kann wenn einer
 verbunden ist.
Ein Client kann z.B. ein PC Tool sein, das die Daten visualisiert,
oder nur auflistet. Es kann aber auch eine andere HW (ESP8266)
sein die nur bestimmte Daten aus dem Datenstrom herausnimmt und
darstellt bzw. anzeigt.

: Bearbeitet durch User
von Hmmm (hmmm)


Lesenswert?

Bot N. schrieb:
> Habe die volle Kontrolle nur über den Server , aber nicht über
> alle Clients!

Dann ist Dein Stichwort TCP-Keepalives, dann kümmert sich der 
TCP/IP-Stack darum.

von Bot N. (botnec)


Lesenswert?

Hmmm schrieb:
> Dann ist Dein Stichwort TCP-Keepalives, dann kümmert sich der
> TCP/IP-Stack darum.

Das scheint er eben nicht zu machen, jedenfalls sieht es für mich so
aus. Ich würde gerne nach maximal einer Minute wissen ob die
Verbindung vom Server zum Client noch da ist oder nicht.

von Hmmm (hmmm)


Lesenswert?

Bot N. schrieb:
> Das scheint er eben nicht zu machen

Die musst Du schon passend konfigurieren.

von Andreas H. (ahz)


Lesenswert?

Bot N. schrieb:
> Habe jetzt noch einen weiteren Ansatz mit Ping gefunden. Werde das
> mal versuchen.

Aber das ist doch Franks Ansatz gewesen ;)

Ping ist eine Anwendung, die das ICMP Protokoll 
(https://de.wikipedia.org/wiki/Internet_Control_Message_Protocol) 
benutzt.

Der Server schickt ein ICMP Packet Typ 8 (Echo Request). Der Client 
antwortet dann mit einem ICMP Packet Typ 0 (Echo Reply).
Ist der Client Offline, dann wird die Anfrage natürlich nicht 
beantwortet.

Das Ganze kann parallel zu anderer IP Communication laufen, stört also 
i.A. nicht.

/regards

von Hmmm (hmmm)


Lesenswert?

Andreas H. schrieb:
> Der Server schickt ein ICMP Packet Typ 8 (Echo Request). Der Client
> antwortet dann mit einem ICMP Packet Typ 0 (Echo Reply).

...oder auch nicht, wie es heutzutage bei vielen Geräten der Fall ist.

von Andreas H. (ahz)


Lesenswert?

Hmmm schrieb:
> Andreas H. schrieb:
>> Der Server schickt ein ICMP Packet Typ 8 (Echo Request). Der Client
>> antwortet dann mit einem ICMP Packet Typ 0 (Echo Reply).
>
> ...oder auch nicht, wie es heutzutage bei vielen Geräten der Fall ist.

Stimmt. Aber, soweit ich weiss, muss es im Client dann explizit disabled 
sein. Denn ohne ICMP würde IP ja nicht wirklich funktionieren, oder?

/regards

von Hmmm (hmmm)


Lesenswert?

Andreas H. schrieb:
> Aber, soweit ich weiss, muss es im Client dann explizit disabled
> sein.

Nein, das ist häufig standardmässig so, z.B. bei aktivierter 
Windows-Firewall.

Andreas H. schrieb:
> Denn ohne ICMP würde IP ja nicht wirklich funktionieren, oder?

Jein. ICMP Echo ("Ping") ist tatsächlich verzichtbar. Wenn man ICMP 
Destination unreachable filtert, kann insbesondere UDP zum Ärgernis 
werden, ausserdem macht man damit die Path MTU Discovery kaputt. ICMP 
Time exceeded ist auch nützlich, ohne funktioniert Traceroute nicht.

von Sherlock 🕵🏽‍♂️ (rubbel-die-katz)


Lesenswert?

Bot N. schrieb:
> Auf welcher Ebene muss denn das passieren?

Auf der Verbindung, die du aufrecht erhalten willst.

> Meine Erfahrung ist, dass die TCPServer TCPClient Verbindung
> grundsätzlich solange hält bis der Client sich ordentlich abmeldet

Irgendwann wirst du vielleicht die Erfahrung machen, dass Firewalls und 
andere Netzwerk-Komponenten die Eigenschaft haben, "eingeschlafene" 
Verbindungen zu trennen. Schlimmer noch: Manche trennen sogar aktiv 
genutzte Verbindungen, wenn sie ein gewisses Alter überschreiten.

Generell sollten Netzwerk-Programme stets sauber mit unerwarteten 
Verbindungsabbrüchen sowie Timeouts (keine Antwort) umgehen können. Denn 
dass eine Verbindung immer stabil bleibt, ist ungewiss. TCP sorgt dafür, 
dass die Daten in der richtigen Reihenfolge und niemals doppelt beim 
Empfangenden Programm ankommen. Sollte das aus irgend einem Grund nicht 
klappen, trennt der IP-Stack üblicherweise die Verbindung.

: Bearbeitet durch User
von Andreas H. (ahz)


Lesenswert?

Hmmm schrieb:
> CMP Echo ("Ping") ist tatsächlich verzichtbar. Wenn man ICMP
> Destination unreachable filtert, kann insbesondere UDP zum Ärgernis
> werden, ausserdem macht man damit die Path MTU Discovery kaputt.

Das war genau das was ich meinte. "Ping" besteht ja letztendlich nur aus 
zwei ICMP Packeten mit unterschiedlichen Typen (8 & 0).
Der Gesamtmechanismus, also ICMP insgesamt, ist schon wichtig.

/regards

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.