AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi Indy TCPServer beenden mit toten Clients
Thema durchsuchen
Ansicht
Themen-Optionen

Indy TCPServer beenden mit toten Clients

Ein Thema von hsg · begonnen am 8. Jun 2012 · letzter Beitrag vom 14. Jun 2012
Antwort Antwort
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#1

AW: Indy TCPServer beenden mit toten Clients

  Alt 12. Jun 2012, 12:28
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.


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
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.

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:
* 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
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.010 Beiträge
 
Delphi 2009 Professional
 
#2

AW: Indy TCPServer beenden mit toten Clients

  Alt 12. Jun 2012, 13:12
So, nun werde ich meine Delphi-Umgebung zerstören in dem ich die aktuelle Indy-Version einspiele
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
Michael Justin
  Mit Zitat antworten Zitat
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#3

AW: Indy TCPServer beenden mit toten Clients

  Alt 12. Jun 2012, 14:48
So, nun werde ich meine Delphi-Umgebung zerstören in dem ich die aktuelle Indy-Version einspiele
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
Wie installierst du denn das Zeug?
Wenn ich das richtig sehe, muss ich ja dieses Fulld10.bat (BDS2006) aufrufen, aber dann installiert der ja alles in irgendwelchen vordefinierten Verzeichnissen, oder?
Ein ReadMe im Zip-File wäre nett gewesen
Wenn du nur die Pfade setzt, wie stellst du sicher, dass nicht die fertigen Pakete dir in die Suppe spucken?

Für heute gebe ich erst mal auf, denn es ist endlich Feierabend! (und wieder nichts geschafft )
  Mit Zitat antworten Zitat
mjustin

Registriert seit: 14. Apr 2008
3.010 Beiträge
 
Delphi 2009 Professional
 
#4

AW: Indy TCPServer beenden mit toten Clients

  Alt 12. Jun 2012, 16:11
Wie installierst du denn das Zeug?
Wenn ich das richtig sehe, muss ich ja dieses Fulld10.bat (BDS2006) aufrufen, aber dann installiert der ja alles in irgendwelchen vordefinierten Verzeichnissen, oder?
Ein ReadMe im Zip-File wäre nett gewesen
Wenn du nur die Pfade setzt, wie stellst du sicher, dass nicht die fertigen Pakete dir in die Suppe spucken?
Nach dem Entpacken hat man die Quelltexte in den Verzeichnisse /Indy10.5.8/Lib/Source, Protocols und System. Wenn Delphi diese in den Projektsuchpfaden findet, werden die installierten Indy Packages nicht verwendet und es gibt keine Konflikte. (Ausser in den Fällen in denen man DCU Dateien ohne Source in den Pfaden hat, die mit einer anderen Indy Version kompiliert wurden).

Wenn in allen meinen Projekten keine Designtimekomponenten von Indy (oder davon abhängige andere Komponenten) benutzt werden, kann ich die Indy Packages auch deinstatallieren, zumindest in den installierten Packages abwählen.
Michael Justin
  Mit Zitat antworten Zitat
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#5

AW: Indy TCPServer beenden mit toten Clients

  Alt 13. Jun 2012, 05:57
So, habe nun die neuere Version der Indys probiert. Leider das gleiche Ergebnis.

Ich werde mir jetzt mal das ganze mit dem ICS-Zeugs ansehen. Leider ist die Dokumentation von den Komponenten mehr als dürftig Wenn also noch jemand ein paar Links hat, immer her damit!
  Mit Zitat antworten Zitat
taveuni

Registriert seit: 3. Apr 2007
Ort: Zürich
542 Beiträge
 
Delphi 11 Alexandria
 
#6

AW: Indy TCPServer beenden mit toten Clients

  Alt 13. Jun 2012, 08:02
Da hats massig Beispiele dabei (OverbyteIcsV7\Delphi\Internet\).
Ausserdem eine aktive Newsgroup.
Die obige Aussage repräsentiert meine persönliche Meinung.
Diese erhebt keinen Anspruch auf Objektivität oder Richtigkeit.

Geändert von taveuni (13. Jun 2012 um 08:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#7

AW: Indy TCPServer beenden mit toten Clients

  Alt 13. Jun 2012, 08:21
Hi,

wäre es möglich Deinen gesamten Code des OnExecute Events des Servers zu posten ?
Ich habe auch schon lange mit den Problem gekämpft, habe aber jetzt keinerlei Probleme!
Man muss nur ein Paar Sachen beachten:

- GANZ GANZ wichtig keine Exception schlucken, diese müssen zwingend im OnExecute auch auftreten,
ansonsten merkt "die kontrollierende Instanz" von Indy nicht, das überhaupt ein Fehler aufgetreten ist;
Erst beim nächsten WriteLn/ReadLn

- Bitte füge mal folgenden Code ganz oben im OnExecute ein:
Delphi-Quellcode:
  AContext.Connection.IOHandler.CheckForDataOnSource(500); // millisekunden, nach Bedarf varieren
  if not AContext.Connection.Connected then exit;
  if not AContext.Connection.IOHandler.InputBufferIsEmpty then
  begin
    // hier Deinen ganz normalen Ablauf implementieren
  end
  else begin
    // Keine Daten im InputBuffer; theoretisch muss nichts gemacht werden; auch kein SLEEP !
    //
    // hier könnte man gut überprüfen, wann der letzte "Kontakt"/Datenaustausch mit dem Client war
    // ist dieser länger her als Dein definierter Timeout, dann einfach etwas in die Connection schreiben
    // das kann ein "NOOP" Kommando sein, aber auch ein Kommando auf das der Client gar nicht kennt
    // das Schreiben dient nur dazu um wirklich eine Exception auszulösen, die Indy dann handeln kann.
    // Bestehend die Connection noch kommt das Kommando normal beim Client an und
    //kann behandelt oder ignoriert werden
    AContext.connection.Socket.WriteLn('NOOP');
    // oder:
    // AContext.connection.Socket.WriteLn('STFU'); // ;-)
  end;
- Des Weiteren ist es sehr zu empfehlen, wie auch schon mehrfach vorher erwähnt wurde,
das Protokoll so aufzubauen das es ein "NOOP" Kommando gibt,
ebenso ein "QUIT/EXIT" Kommando

- Ich für meinen Teil gehe immer so wat das ich mit ein TClient-Objekt erstelle und diese in der Eigenschaft
AContext.Data mitführe. Zusätzlich zu den Eigenschaft die das TClient-Objekt definieren,
führe ich immer noch eine Property LastContact oder LastTimeStamp oder whatever mit,
die mir die Information liefert, wann zum letzten mal Erfolgreich Daten gelesen oder geschrieben wurden.

Wenn das alles beherzigt wird, gibt es keinerlei Probleme mit "Zombie" Clients.

Greetz Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
hsg

Registriert seit: 24. Apr 2006
Ort: Wustermark
354 Beiträge
 
Delphi 10.3 Rio
 
#8

AW: Indy TCPServer beenden mit toten Clients

  Alt 13. Jun 2012, 10:26
Hi,

...
Wenn das alles beherzigt wird, gibt es keinerlei Probleme mit "Zombie" Clients.

Greetz Data
Hi,

ich habe die (reduzierte) Datei mal angehängt. Deine Hinweise sind entsprechend eingebaut.
Im gesamten Programm werden im Moment nur ganz wenige Exceptions abgefangen (und auch nur an den dringendsten Stellen).

Wir führen bereits ein TClient-Objekt mit, allerdings ohne TimeStamp oder dergleichen.
Das Noop-Kommando habe ich jetzt für den Versuch mit eingebaut, wird aber in der Realität nicht möglich sein, da es ein paar ältere Clients gibt, die mit den NOOP-Meldungen nicht zurande kommen werden (Update auf neue Version wahrscheinlich nicht möglich)

Ich weise noch mal (vorsichtshalber) darauf hin: Es gibt nur dann Probleme, wenn der Clientrechner im Netzwerk (physikalisch) nicht mehr erreichbar ist.
Egal, ob Clientprogramm läuft oder nicht.

Das ist auch in der jetzigen Version so.

Bei Bedarf (und jemand sich mit dem netten DeviceEmulator von Microsoft auskennt) kann ich auch den Client zur Verfügung stellen Damit kann man dann recht elegant das Phänomen deutlich machen.
Angehängte Dateien
Dateityp: pas uPDAServer.pas (14,3 KB, 6x aufgerufen)
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:30 Uhr.
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