AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Thread stürzt ab Indy TCPIP Client
Thema durchsuchen
Ansicht
Themen-Optionen

Thread stürzt ab Indy TCPIP Client

Ein Thema von Barthiboy · begonnen am 9. Jan 2015 · letzter Beitrag vom 13. Jan 2015
Antwort Antwort
Seite 1 von 2  1 2      
Barthiboy

Registriert seit: 4. Nov 2011
36 Beiträge
 
#1

Thread stürzt ab Indy TCPIP Client

  Alt 9. Jan 2015, 08:06
Hallo zusammen.

Folgende Konstellation:
Siemens Steuerung S7 == Server, selbst geschrieben SCL mit Simatic Manager
Win7 Prof PC == Client, selbst geschrieben Delphi XE5
Kommunikation über TCPIP

Folgendes Problem im Client:
Mein Client kann mit verschiedenen SPSen kommunizieren.
Hierfür erzeuge ich pro SPS einen Thread, in welchem ich mit der Indykomponente über TCP/IP kommuniziere.
Das funktioniert soweit auch ganz gut.
Wenn ich die Steuerung Neustarte oder Reset betätige wird die Verbindung vom Server geschlossen.
Wenn die Steuerung allerdings ausgeschaltet wird, ist der Server ja nicht mehr da und die Verbindung bricht ab.
Dabei stürzt der Kommunikationsthread gleich komplett ab.
Hier ein Auszug aus dem Logger:

07:38:38 SPS2Client : Die Verbindung wurde erfolgreich geschlossen.
07:38:40 SPS2Client : Die Verbindung wurde erfolgreich geschlossen.
07:38:49 SPS2Client : Zeitüberschreitung beim Lesen.
07:38:51 SPS2Client : Die Verbindung wurde erfolgreich geschlossen.
07:38:52 SPS2Client : Die Verbindung wurde erfolgreich geschlossen.
07:38:53 SPS2Client : Die Verbindung wurde erfolgreich geschlossen.
07:38:55 SPS2Client : Die Verbindung wurde erfolgreich geschlossen.
07:38:56 SPS2Client : Die Verbindung wurde erfolgreich geschlossen.
07:38:59 SPS2Client : Die Verbindung wurde erfolgreich geschlossen.
07:39:05 SPS2Client : Socket-Fehler # 10053Software verursachte einen Verbindungsabbruch.

Alle Einträge außer der Letzte sind druch Neustart oder Reset entstanden.
Danach verbindet der Thread auch gleich wieder neu.
Beim letzen Eintrag schmiert der Thread komplett ab.
Ist im Thread-Status Fenster auch nicht mehr zu sehen.

Weiß jemand woran das liegen kann. Bzw. wie ich nach dem Fehler suchen kann?
Eigentlich werden alle Exceptions mit geloggt.

Vielen Dank schon mal.
Hier die Execute procedure
Delphi-Quellcode:
procedure TKommSPS.Execute;
var
  freq: Int64;
  startTime: Int64;
  endTime: Int64;
  Time : Int64;
  i : Integer;
begin
  QueryPerformanceFrequency(freq);
  // Kommunikations-Thread Hauptschleife
  while not Terminated do begin
    while FKommEnable and not Terminated do begin
      try
        // Wenn nicht verbunden
        if (not FIdTCPClient.Connected) and not Terminated then begin
          if FLogger <> nil then begin
            FLogger.LogMessage(TimeToStr(now) + ' SPS' + IntToStr(SPS) + 'Client : ' + 'Connecting');
          end;
          FIdTCPClient.Connect;
        end;
        // Wenn verbunden
        if FIdTCPClient.Connected and not Terminated then begin
          FKommAktiv := true;
          // Zeitmessung just for performancetest
          QueryPerformanceCounter(endTime);
          Time := endTime - startTime;
          QueryPerformanceCounter(startTime);

          // Priority Aufträge abarbeiten
          if FPriorityKommAuftrag <> nil then begin
            for i := 0 to length(FPriorityKommAuftrag) - 1 do begin
              Auftragsenden(FPriorityKommAuftrag[i].Form, FPriorityKommAuftrag[i].Auftrag, FPriorityKommAuftrag[i].RdWrt);
              Auftragempfangen(FPriorityKommAuftrag[i].Form, FPriorityKommAuftrag[i].Auftrag, FPriorityKommAuftrag[i].RdWrt);
            end;
          end;
          // User Aufträge abarbeiten
          if (length(FKommAuftrag) > 0) then begin
            // Ersten Auftrag in der Liste senden
            // Useraufträge
            Auftragsenden(FKommAuftrag[0].Form, FKommAuftrag[0].Auftrag , FKommAuftrag[0].RdWrt);
            Auftragempfangen(FKommAuftrag[0].Form, FKommAuftrag[0].Auftrag , FKommAuftrag[0].RdWrt);
            Auftragverwalten();
          end;
          // Kommunikation visualisieren
          Synchronize(Btn_Komm_toggle);
        end;
      except
        on E: Exception do begin
          Logger.LogErrorMessage(TimeToStr(now) + ' SPS' + IntToStr(SPS) + 'Client : ' + E.ToString);
          if Assigned(FIdTCPClient.IOHandler) then begin
            FIdTCPClient.IOHandler.InputBuffer.Clear;
          end;
          if FIdTCPClient.Connected then begin
            FIdTCPClient.Disconnect;
          end;
          Synchronize(Btn_Komm_error);
        end;
      end;

      // Nur pausieren wenn nichts zu tun oder disconnected
      if not FIdTCPClient.Connected and not Terminated then begin
        Sleep(500);
      end;
      // Wenn Programm beendet werden soll
      if Terminated then begin
      // Wenn noch eine Verbindung besteht, Verbindung trennen
        if FIdTCPClient.Connected then begin
          FIdTCPClient.Disconnect;
          Exit;
        end;
      end;
    end;
    // Kommunikation ist disabled
    FKommAktiv := false;
    Sleep(300);
  end;
  FIdTCPClient.Free;
  Sleep(0);
end;
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Thread stürzt ab Indy TCPIP Client

  Alt 9. Jan 2015, 10:31
Es werden eben nicht alle Exceptions geloggt, sonst würdest du eine weitere sehen. Das Thread-Objekt hat auch noch eine Exception, die du abfragen kannst, wenn der Thread sich beendet hat.

Delphi-Referenz durchsuchenSystem.Classes.TThread.FatalException

Da findest du deine Exception. Ausgelöst wird diese durch das, was du da in deinem Except-Teil veranstaltest. Der beste Kandidat dafür ist FIdTCPClient.IOHandler.InputBuffer.Clear; .

Das liegt daran, dass du relativ blind bei jeder Exception davon ausgehst, dass du die so behandeln kannst. Dem ist aber nicht so. Bei einer Zugriffsverletzung kannst du das so eben nicht behandeln.

Darum gibt man auch explizit die Exceptions an, die man behandeln kann. Wäre in deinem Falle irgendeine der EIdExcetion s. Dem Socket-Fehler kann man so eben nicht beikommen. Im Extremfall schmeisst du mit FreeAndNil den Tcp-Client einfach aus dem Speicher und am Anfang der Schleife erstellst du bei Bedarf den Client.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Barthiboy

Registriert seit: 4. Nov 2011
36 Beiträge
 
#3

AW: Thread stürzt ab Indy TCPIP Client

  Alt 9. Jan 2015, 11:07
Hallo

danke für die Antwort.
Das Ereignis OnTerminateKommSPS wird nicht ausgelöst. Ich kann die Exception als nicht abfragen oder?
Welche EIdExcetion´s muss man den abfangen, bzw. was spricht dagegen den Buffer zu clearen?
Warum führt das zu einer Exception? Über if Assigned(FIdTCPClient.IOHandler) then begin frage ich doch ab ob er da ist!?

Danke
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Thread stürzt ab Indy TCPIP Client

  Alt 9. Jan 2015, 11:24
Es gibt bei Exceptions kein "welche muss ich" sondern immer nur ein "welche kann ich" behandeln

Wenn du den InputBuffer (Instanz) löschst und fragst, ob es einen IOHandler (Instanz) gibt, wie kommst du darauf, dass es auch einen InputBuffer geben muss?

So wäre es schon mal bis zum Schluss geprüft:
Delphi-Quellcode:
if { Assigned( FFoo ) and } Assigned( FFoo.IOHandler ) and Assigned( FFoo.IOHandler.InputBuffer ) then
  FFoo.IOHandler.InputBuffer.Clear;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Barthiboy

Registriert seit: 4. Nov 2011
36 Beiträge
 
#5

AW: Thread stürzt ab Indy TCPIP Client

  Alt 9. Jan 2015, 11:39
Also ich habe die Abfrage jetzt mal so rein.
Allerdings immer noch mit dem gleichen Effekt.
Woher weiß ich welche Exceptions ich behandeln kann?

Zitat:
Wenn du den InputBuffer (Instanz) löschst und fragst, ob es einen IOHandler (Instanz) gibt, wie kommst du darauf, dass es auch einen InputBuffer geben muss?
Ich frag doch zuerst und lösche dann, oder steh ich jetzt voll daneben!?

Edit:

Ich habe jetzt FIdTCPClient.IOHandler.InputBuffer.Clear; komplett rausgeschmissen.
Der Fehler tritt jetzt wesentlich weniger auf.
Aber bei excesivem Steuerung reset, Neuanlauf usw. bekomme ich immer noch folgende Meldung:
Socket-Fehler # 10054Die Verbindung wurde von Peer zurückgesetzt.

Also muss ich das wohl irgendwie doch noch abfangen

Geändert von Barthiboy ( 9. Jan 2015 um 11:56 Uhr)
  Mit Zitat antworten Zitat
Barthiboy

Registriert seit: 4. Nov 2011
36 Beiträge
 
#6

AW: Thread stürzt ab Indy TCPIP Client

  Alt 9. Jan 2015, 12:01
ich habe hier einen ähnlichen Fall gefunden:
http://www.delphipraxis.net/163393-i...-umleiten.html

In dem letzten Eintrag steht wohl die Lösung.
Aber nachvollziehen kann ich das noch nicht.
Vor allem frage ich vorher ab ob die Verbindung überhaupt besteht.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#7

AW: Thread stürzt ab Indy TCPIP Client

  Alt 9. Jan 2015, 12:24
Deine Execute-Methode ist irgendwie zu lang und unhandlich ... (würde ich so nie implementieren). Teile die auf, dann wird das wesentlich einfacher:

Delphi-Quellcode:
TFoo.Execute;
var
  LClient : TClient;
begin
  LClient := nil;
  try
    while not Terminated do
    try
      // Eine Client-Instanz garantieren
      if not Assigned( LClient ) then
      begin
        LClient := TClient.Create;
      end;
      
      ExecuteOnCLient( LClient );

    except
      on E: EIdSpecialException do
      begin
        // Loggen der Exception

       // Client benötigt nur einen Reset
       LClient.Reset;
      end;
      on E: EIdException do
      begin
        // Loggen der Exception
       
       // Zerstören der Client-Instanz
       FreeAndNil( LClient );
      end;
      on E: Exception do
      begin
        // Loggen der Exception
        
        raise; // Exception raisen -> der Thread wird beendet
      end;
    end;
  finally
    LClient.Free;
  end;
end;

procedure TFoo.ExecuteOnCLient( AClient : TClient );
begin
  // Hier geht es jetzt los mit der eigentlichen Verarbeitung
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo ( 9. Jan 2015 um 12:33 Uhr)
  Mit Zitat antworten Zitat
Barthiboy

Registriert seit: 4. Nov 2011
36 Beiträge
 
#8

AW: Thread stürzt ab Indy TCPIP Client

  Alt 12. Jan 2015, 07:09
Danke für deine Antworten.

ich habe noch folgende Probleme:
TIdTCPClient.Reset gibt es bei mir nicht v.10.6.0.504.
EIdSpecialException gibt es bei mir nicht v.10.6.0.504. Oder ich kanns nicht finden.

Aber sonst sieht es so aus als hättest du mir viel weiter geholfen.
  Mit Zitat antworten Zitat
Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#9

AW: Thread stürzt ab Indy TCPIP Client

  Alt 12. Jan 2015, 09:05
Und wo hast du TFoo und TClient gefunden?

Der Code ist nur dazu da, das Prinzip zu erläutern und keine CopyPaste Lösung. Anfangen würde ich auch zunächst auch damit, bei jeder Indy Exception EIdException den Client einfach aus dem Speicher zu entfernen.

Dann schaut man sich das Log an und die aufgetretenen Exceptions und prüft, bei welcher Exception man noch etwas retten könnte. Allerdings wäre es mir auch egal, denn wenn der Betrieb so gewährleistet werden kann ... who cares? Da bräuchte ich schon bessere Gründe.
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)
  Mit Zitat antworten Zitat
Barthiboy

Registriert seit: 4. Nov 2011
36 Beiträge
 
#10

AW: Thread stürzt ab Indy TCPIP Client

  Alt 12. Jan 2015, 09:15
OK. Prinzip is jetzt klar.
Du hast mir viel geholfen. Vielen Dank.

Die Verbindungsprobleme, die ich hervorrufen konnte sind somit alle beseitigt.
Jetzt muss ich mir nur überlegen, was ich bei einer Zugriffsverletzung usw. mache.
Aber das soll (bis jetzt) mal noch nicht dein Problem sein
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


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 19:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz