Einzelnen Beitrag anzeigen

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