Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Problem mit TIdTCPServer, kein sauberes Beenden möglich (https://www.delphipraxis.net/42421-problem-mit-tidtcpserver-kein-sauberes-beenden-moeglich.html)

Tigger 18. Mär 2005 15:06


Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
Hallo zusammen!
Ich sitze immer noch an meinem Schiffe-versenken. Habe das Problem, dass sich das Programm nicht sauber beenden läßt.
Ich arbeite mit den Indy-Komponenten, im speziellen geht es hier um den TIdTCPServer.

Wenn der Client die Verbindung unterbricht, wird folgende Prozedur ausgeführt:
Delphi-Quellcode:
procedure Tfrm_main.TCP_ServerDisconnect(AThread: TIdPeerThread);
//******************************************************************************
//Prozedur OnDisconnect. Wird ausgeloest, wenn der Client vom Server getrennt wird
//------------------------------------------------------------------------------
// Schnittstelle
// IN: AThread - TIdPeerThread - Der Thread der Disconnect ausloest
//******************************************************************************
var ThreadList:TList;
begin
    if verbindungSteht then
    begin
       // Verbindung trennen
       sendeSysLog('Verbindung unterbrochen');
       AThread.Connection.Disconnect;
       Statusbar1.Panels[0].Text:= 'Die Verbindung zum Client wurde verloren... (On Disconnect)';
       unterbrochen:= true;
       verbindungSteht:= false;
       PingThread.Suspend;
       TCP_Server.Active := false;
    end;
end;
Beim Deaktivieren des TCP-Servers dauert es einen Moment, dann kommt eine Exception "EIdTerminateThreadTimeout
'Zeitüberschreitung bei Beenden von Thread' ".

Wenn ich den Server schliesse, folgende Prozedur:
Delphi-Quellcode:
procedure Tfrm_main.FormClose(Sender: TObject; var Action: TCloseAction);
//******************************************************************************
//  Formular wird geschlossen
//******************************************************************************
var ThreadList:TList;
begin
    sendeSyslog('Formular wird geschlossen');

    try
      if TCP_Server.Active then
        TCP_Server.Active := false;
      if PingThread <> nil then
        PingThread.Terminate;
      ServerSocket.Active := false;
      TCP_Server.ThreadMgr.TerminateThreads;
      SysLog.Active := false;
    except //einfach nur abfangen
    end;

    verbindungSteht:= false;
end; //FormClose
Danach tritt sofort folgende Exception auf: "EIdClosedSocket 'Verbindung aufgehoben' ".

Wenn ich breakpoints setze, wird die Exception wie gesagt immer beim Deaktivieren des TCP-Servers ausgelöst. Nehme ich diese Code-Teile komplett aus dem Programm raus, tritt trotzdem die Exception mit 'Verbindung aufgehoben' auf und zwar beim Beenden des Programms, also direkt nach dem Application.run bei "end.".

Hat jemand so auf Anhieb eine Idee, wo der Hund begraben ist?

Gruß, Tigger

Tigger 19. Mär 2005 15:06

Re: Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
Ist die Frage zu blöd, liest hier am Wochenende keiner
oder gibt es einfache keine Antwort auf die Frage?

Tigger

Tigger 20. Mär 2005 16:21

Re: Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
49 Stunden und immer noch keine Antwort....

Ist denn theoretisch richtig, was ich da mache?
Allmählich gehen mir die Ideen aus.

Tigger

etom291272 20. Mär 2005 16:36

Re: Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
bin mir nicht sicher ob ich dir helfen kann aber ich versuchs mal da sonst keiner geschrieben hat.

Habe mir in den letzten tagen mit den indy komponenten einen kleinen lizenzserver gebastelt und bin über einiges gestolpert.

ich verwende einfach folgende codes wenn sich ein client bei mir sind 9999 möglich ausloggt. oder beim beenden des programms funktioniert bei mir einwandfrei ohne exceptions

Delphi-Quellcode:
procedure TFmMain.IdTCPServerDisconnect(AThread: TIdPeerThread);
begin
  AdvSpinEdit1.Value:=AdvSpinEdit1.Value-1;
  StPanLizSrv.Panels[1].Text:=FixtextPan2+inttostr(AdvSpinEdit1.Value);
end;


function TFmMain.StopServer: Boolean;
begin
try
  IdTCPServer.Active := false;
  IdTCPServer.Bindings.Clear;

  Result := not IdTCPServer.Active;

  fServerRunning := result;

  if result then StPanLizSrv.Panels[0].Text:=FixtextPan1+'deaktiviert'
            else StPanLizSrv.Panels[0].Text:=FixtextPan1+'aktiviert';
except
end;          
end;
in dem advspinedit speicher ich die gerade aktiven clients und beim schliessen des formulars ruf ich
die stopserver function auf

:!: in der delphi ide kommen exceptions (logisch) wenn ein client einfach abbricht
aber als kompelierte exe gestartet funzt das toll.

UweR 21. Mär 2005 07:13

Re: Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
Hallo Tigger,

du disconnectest (schönes Wort) eine schon nicht mehr bestehende Verbindung. Schmeiß einfach mal den Disconnect-Befehl raus. Ich denke daran liegts.

Tigger 22. Mär 2005 08:12

Re: Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
Zitat:

Schmeiß einfach mal den Disconnect-Befehl raus. Ich denke daran liegts.
Leider nicht... Die Fehlermeldungen bleiben die gleiche, auf beiden Seiten. Außerdem ist die Verbindung ja noch nicht unterbrochen, wenn ich das Server-Programm schließe.

Noch andere Ideen? Bin kurz davor, das Ganze nochmal komplett neu zu machen...

Tigger

soulflare 14. Okt 2005 12:15

Re: Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
Ich habe das gleiche Problem. Hast du es irgendwie hingekriegt tigger?
Oder hat jemand anders ne Lösung? Ich verzweifle hier bald. :(

Net7 14. Okt 2005 12:26

Re: Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
Mal versucht an der TIdTCPServer.TerminateWaitTime zu spielen.
Vielleicht liegt es daran. Erhöhe doch mal auf 10000.
Nur so eine Idee.

Mfg Net7

supermuckl 14. Okt 2005 14:29

Re: Problem mit TIdTCPServer, kein sauberes Beenden möglich
 
tja ganz einfach zu erklären
die ondisconnect wird über den clientthread ausgeführt und ist somit multithreaded
wenn du also in dem ondisconnect code steckst, steckst du in einem thread !!!
also 1. mit synchronisations-objekten arbeiten (TCriticalSection z.b.)
und 2. kannst du (weshalb der fehler kommt) dich nicht selbst terminieren *g* so wie im Terminator film
also.. du steckst ja im code eines threads und willst den selbigen beenden -> fehler

der thread wird sowieso selbst beendet und der socket disconnected von den Indys.. also manuelles kicken von solchen verbindungen einfach sein lassen (wenn sie eh schon durch einen fehler zu einem disconnect durch indy führen)


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:56 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