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;