Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Indy TCPServer beenden mit toten Clients (https://www.delphipraxis.net/168753-indy-tcpserver-beenden-mit-toten-clients.html)

hsg 11. Jun 2012 06:34

AW: Indy TCPServer beenden mit toten Clients
 
Zitat:

Zitat von mjustin (Beitrag 1170047)

Werden Exceptions eventuell so behandelt, dass Indy sie nicht bemerkt? Indy verwendet einige (selbstdefinierte) Exceptions wie EIdConnClosedGracefully zur Steuerung:

Zitat:

You need to get rid of your exception handling, or at least re-raise any EIdException-derived exceptions you catch. You are blocking Indy's internal notifications from being dispatched and processed correctly.
(https://forums.embarcadero.com/messa...ssageID=257582)

Es gibt zwar an ein- zwei Stellen ein Exception-Handling, aber auch das wird nicht getriggert.
Es herrscht einfach nur Schweigen im Walde :(

hsg 11. Jun 2012 06:52

AW: Indy TCPServer beenden mit toten Clients
 
Zitat:

Zitat von sx2008 (Beitrag 1170176)
Nur wer Daten sendet, kann erkennen dass die Verbindung unterbrochen ist.

Es wird ja vorweg gesendet (Die Close_Request-Message), trotzdem erkennt der Server nicht das er alleine auf weiter Flur steht.
Das Beenden von unterbrochenen Verbindungen geht ja zum Teil. Nur wenn das angesprochene Gerät selbst nicht mehr im Netz ist, hängt sich der Server auf. Ist das Gerät im Netz, klappt auch das Beenden ohne Probleme.

hsg 11. Jun 2012 07:36

AW: Indy TCPServer beenden mit toten Clients
 
Zitat:

Zitat von mjustin (Beitrag 1170180)
noch ein sauberes Beenden der Verbindung? (Schliessen des Sockets)

Delphi-Quellcode:

AContext.Connection.Disconnect
Wenn das Protokoll geändert werden kann, wäre ein Heartbeat-Verfahren eventuell eine Verbesserung, damit der Server verloren gegangene Verbindungen schneller erkennt und abräumt.

Update:

unter http://www.delphipraxis.net/157267-i...er-thread.html

werden noch diese Zeilen regelmäßig im Server OnExecute ausgeführt:
Delphi-Quellcode:
    AContext.Connection.IOHandler.CheckForDisconnect(False, True);
    AContext.Connection.CheckForGracefulDisconnect(False);

Jein :) Wird ein Disconnect vom Server versucht, hängt sich der Thread beim Beenden des Servers auf (das Problem, welches auch im verlinkten Post beschrieben wird).
Diese Hänger habe ich dadurch beseitigen können, dass der Server auf die Abmeldung (oder nicht Abmeldung) der Clients wartet. Das Server.Active := false macht übrigens auch ein Disconnect auf die vorhandenen Clients, deswegen das Jein.

Ich habe die Zeilen von oben mal im OnExecute eingebaut, keine Veränderung.
Mal eine Auflistung der Testszenarios und deren Auswirkung:

* Client meldet sich an Server an und Server wird beendet: Alles einwandfrei, der Client meldet sich ab und der Server beendet sich sauber.

* Client meldet sich an Server an, verliert die Connection, meldet sich nach Herstellung der Netzwerkverbindung erneut an Server an. Server wird beendet: Es sind zwei Connections in der Liste aufgelistet. Eine tote und eine aktive. An beiden wird das Ende-Signal gesendet. Der Server bekommt eine Exception (Socket-Error 10054) und beendet sich dann sauber.

* Client meldet sich an Server an, verliert die Connection. Redet nicht mit dem Server nach Herstellung der Netzwerkverbindung. Server wird beendet: Die tote Connection wird beendet und der Server bekommt eine Execption (Socket-Error 10054) und beendet sich dann sauber.

* Client meldet sich an Server an, verliert die Connection und kommt nicht wieder ins Netz. Server wird beendet: Es wird die Meldung an den toten Client gesendet und Server hängt sich auf. KEINE Exception, keine andere Meldung.

Wie gesagt: Nur wenn der Client netzwerktechnisch nicht mehr erreichbar ist, hängt sich der Server komplett auf.

hsg 11. Jun 2012 07:44

AW: Indy TCPServer beenden mit toten Clients
 
Zitat:

Zitat von himitsu (Beitrag 1170198)

Leider läßt sich dagegen nichts machen. (wir haben alles Mögliche versucht)

Zum Teil ist das auch ein Problem von Windows, denn dieses schließt die Ports nicht, wenn die Connection abreißt, womit Indy (im Server oder auch im Client) nicht darüber informiert wird, daß die Connection eigentlich weg ist.

Kann man da wirklich nichts gegen machen? Da unsere Leute sich recht gerne aus dem WLan-Bereich entfernen und sie auch mal gerne vergessen, die Geräte in die Ladestationen zu stellen, kommt es leider öfters zu diesen Netzwerkabbrüchen.
Der Rechner, auf dem der Server läuft, wird aus bestimmten Gründen jede Nacht neugestartet (automatisiert!) Da ist ein nicht beendenbarer Server sehr hinderlich :(

NickelM 11. Jun 2012 08:09

AW: Indy TCPServer beenden mit toten Clients
 
Abgesehen von den technischen TCP Problemen, funktioniert der automatisierter Neustart richtig?
Oder ist es schon vorgekommen, dass der Server am nächsten Tag nicht mehr Erreichbar ist, da der Server nicht beendet werden konnte?
Das klingt jetzt nach einer "Hammer auf Kopf"-Methode, aber ich würd sagen, dass du diesen Thread, falls er hängt mit TerminateThread WinAPI "crashst", oder direkt die ganze Anwendung von einer Anwendung "crashen" lässt mit TerminateProcces oder so.
Ist eine Recht unschöne Methode zum Neustart. Aber immerhin würde der Server weiterfunktionieren...zumindest am nächsten Tag :-D
Ich weis das lösst echt nicht dass Problem, aber immerhin müsstest du ihn nicht mehr von Hand neustarten.

Es wäre aber echt meine persönliche letzte Idee, um diesen Problem zuumgehen, wenn nichts anderes gehen würde.

EDIT: Ehm ja...sorry :oops: Der ganze Rechner wird ja neugestartet, also macht das kein Unterschied. :oops:

Gruß NickelM

taveuni 11. Jun 2012 10:22

AW: Indy TCPServer beenden mit toten Clients
 
Ich hab jetzt nicht alles durchgelesen aber:

Kannst Du Dich von Indy lösen und ICS oder Synapse verwenden?
Bei ICS gibts die Methode CloseDelayed. Da werden alle Verbindungen
geschlossen auch die von nicht mehr verbundenen Client Klassen.
Und da hängt auch nichts.

hsg 11. Jun 2012 12:20

AW: Indy TCPServer beenden mit toten Clients
 
Zitat:

Zitat von taveuni (Beitrag 1170281)
Kannst Du Dich von Indy lösen und ICS oder Synapse verwenden?

Werde mir beides ansehen.

mjustin 12. Jun 2012 12:01

AW: Indy TCPServer beenden mit toten Clients
 
Zitat:

Zitat von hsg (Beitrag 1170256)
Zitat:

Zitat von himitsu (Beitrag 1170198)

Leider läßt sich dagegen nichts machen. (wir haben alles Mögliche versucht)

Zum Teil ist das auch ein Problem von Windows, denn dieses schließt die Ports nicht, wenn die Connection abreißt, womit Indy (im Server oder auch im Client) nicht darüber informiert wird, daß die Connection eigentlich weg ist.

Kann man da wirklich nichts gegen machen? Da unsere Leute sich recht gerne aus dem WLan-Bereich entfernen und sie auch mal gerne vergessen, die Geräte in die Ladestationen zu stellen, kommt es leider öfters zu diesen Netzwerkabbrüchen.
Der Rechner, auf dem der Server läuft, wird aus bestimmten Gründen jede Nacht neugestartet (automatisiert!) Da ist ein nicht beendenbarer Server sehr hinderlich :(

Es ist bei TCP völlig normal, dass der Server nicht erfährt wenn ein Client nicht mehr im Netzwerk ist. Der Indy TCP Server kann damit auch problemlos umgehen, und sich sauber beenden, ohne dass die Clients dazu noch irgendetwas tun müssen.

Ist das Problem auch mit der aktuellen Indy 10.5.8 Version nachvollziehbar?

Um die Ursache einzugrenzen würde ich eine Testversion der Anwendung bauen, in der das Problem ohne Zugriff auf externe Hardware nachvollziehbar ist, durch einen "simulierten" Client. Danach würde ich die Anwendung so weit reduzieren wie es möglich ist und der Fehler noch nachvollziehbar ist.

Zitat:

* Client meldet sich an Server an, verliert die Connection und kommt nicht wieder ins Netz. Server wird beendet: Es wird die Meldung an den toten Client gesendet und Server hängt sich auf. KEINE Exception, keine andere Meldung.
Wenn es kein WLAN wäre, entspricht das "Anmelden, dann Netzwerkkabel des Clients entfernen", oder einfach "Anmelden, dann den Client abschalten".

Zitat:

* Client meldet sich an Server an, verliert die Connection, meldet sich nach Herstellung der Netzwerkverbindung erneut an Server an. Server wird beendet: Es sind zwei Connections in der Liste aufgelistet. Eine tote und eine aktive. An beiden wird das Ende-Signal gesendet. Der Server bekommt eine Exception (Socket-Error 10054) und beendet sich dann sauber.
Bei welcher der beiden Connections kommt die Exception? Seltsam, dass das zweite Anmelden dazu führt, dass die erste (dann "tote") Verbindung beim Herunterfahren keinen Hänger mehr auslöst - und wenn das zweite Anmelden nicht erfolgt, der Hänger auftritt.

hsg 12. Jun 2012 12:28

AW: Indy TCPServer beenden mit toten Clients
 
Zitat:

Zitat von mjustin (Beitrag 1170414)
Es ist bei TCP völlig normal, dass der Server nicht erfährt wenn ein Client nicht mehr im Netzwerk ist. Der Indy TCP Server kann damit auch problemlos umgehen, und sich sauber beenden, ohne dass die Clients dazu noch irgendetwas tun müssen.

Ist das Problem auch mit der aktuellen Indy 10.5.8 Version nachvollziehbar?

Sorry, dass habe ich verschwitzt zu testen. Bin gestern und heute eh noch nicht dazu gekommen, an dem Problem effektiv herumzutesten.


Zitat:

Zitat von mjustin (Beitrag 1170414)
Um die Ursache einzugrenzen würde ich eine Testversion der Anwendung bauen, in der das Problem ohne Zugriff auf externe Hardware nachvollziehbar ist, durch einen "simulierten" Client. Danach würde ich die Anwendung so weit reduzieren wie es möglich ist und der Fehler noch nachvollziehbar ist.

Das ist kein Problem :-D
Der Testclient ist der WindowsMobile-DeviceEmulator, dem klaue ich mit einem Tastendruck das Netzwerk und gebe es ihm wieder, der Server ist (bis auf die Execute-Methode und dem notwendigen Beiwerk auch relativ schlank.

Zitat:

Zitat von mjustin (Beitrag 1170414)
Wenn es kein WLAN wäre, entspricht das "Anmelden, dann Netzwerkkabel des Clients entfernen", oder einfach "Anmelden, dann den Client abschalten".

Korrekt. So ist der Stresstest bei mir zur Zeit ja auch aufgebaut. Der DeviceEmulator spielt ja seine Netzwerkverbindung über ein simuliertes WLan.

Zitat:

Zitat von mjustin (Beitrag 1170414)
Zitat:

* Client meldet sich an Server an, verliert die Connection, meldet sich nach Herstellung der Netzwerkverbindung erneut an Server an. Server wird beendet: Es sind zwei Connections in der Liste aufgelistet. Eine tote und eine aktive. An beiden wird das Ende-Signal gesendet. Der Server bekommt eine Exception (Socket-Error 10054) und beendet sich dann sauber.
Bei welcher der beiden Connections kommt die Exception? Seltsam, dass das zweite Anmelden dazu führt, dass die erste (dann "tote") Verbindung beim Herunterfahren keinen Hänger mehr auslöst - und wenn das zweite Anmelden nicht erfolgt, der Hänger auftritt.

Es ist die tote Verbindung, bei der die Exception auftaucht.
Wie gesagt, dass Problem besteht nur wirklich dann, wenn die Netzwerkverbindung nicht vorhanden ist. Also das Gerät auch mittels Ping nicht erreichbar ist.
Der Server lässt sich sauber beenden, wenn die physikalische Netzwerkverbindung zwischen Server-Rechner und Client-Rechner besteht. Besteht diese Verbindung nicht, hängt der Server.
Ich hoffe, so ist es ein wenig klarer geworden.

So, nun werde ich meine Delphi-Umgebung zerstören in dem ich die aktuelle Indy-Version einspiele :-D

mjustin 12. Jun 2012 13:12

AW: Indy TCPServer beenden mit toten Clients
 
Zitat:

Zitat von hsg (Beitrag 1170424)
So, nun werde ich meine Delphi-Umgebung zerstören in dem ich die aktuelle Indy-Version einspiele :-D

Sicherheitshalber installiere ich Indy nie als Komponenten in der IDE, das dauert eh viel zu lange - stattdessen setze ich nur für das Projekt die Pfade Indy/Lib/Core, Prtotocols und System (und lasse die Orignalversion von Indy installiert). Aber "zerstören" ist noch ein zu sanftes Wort für den Indy-Effekt, den ich auch schon kennenlernte :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:35 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz