Ich bin leider erst jetzt wieder im Büro, sorry. Die Instanzen laufen im Kontext des Mainthreads, da es für das Programm recht egal war, dass es zwischendurch für ein paar ms nicht reagiert. 2 von den 3 Verbindungen laufen auch ohne Probleme.
Edit: Jetzt ist die VM auch hochgefahren, so dass ich Code posten kann:
Delphi-Quellcode:
// TCP Komponenten Erstellen
procedure TValueGroup.CreateTCP;
begin
if Assigned(FTCP)
then
begin
if FTCP.Connected
then
FTCP.Disconnect(false);
FreeAndNil(FTCP);
end;
FTCP := TIdTCPClient.Create;
FTCP.IOHandler := TIdIOHandlerStack.Create;
FTCP.IOHandler.ReadTimeout := 1000;
FTCP.Host := FIP;
FTCP.Port := FPort;
FTCP.OnStatus := OnTCPStatus;
end;
Delphi-Quellcode:
// Verbindungsherstellung
procedure TValueGroup.ConnectToGateway;
begin
try
FTCP.ConnectTimeout := 100;
if not FTCP.Connected
then FTCP.Connect();
except
on e:
Exception do
begin
frmTCPLog.Add(FTCP.Host+'
: Connect failed. Recreating.');
try
CreateTCP;
except
end;
end;
end;
end;
Delphi-Quellcode:
// Meine Daten-Refresh Prozedur
procedure TValueGroup.RefreshData;
var
remainingBytes: Integer;
sAdr: Integer;
begin
remainingBytes := FMaxAddress+4 + 2;
SetLength(FBuffer, remainingBytes);
try
if not FTCP.Connected
then
ConnectToGateway;
sAdr := 0;
while remainingBytes > 255
do
begin
FRequestBuffer[1] := Byte(sAdr
shr 8);
FRequestBuffer[2] := Byte(sAdr
and $FF);
FRequestBuffer[4] := 255;
SendBuffer(
TCP, RequestBuffer);
ReceiveBuffer(
TCP, FBuffer, sAdr, 255);
dec(remainingBytes, 255);
inc(sAdr, 255);
end;
FRequestBuffer[1] := Byte(sAdr
shr 8);
FRequestBuffer[2] := Byte(sAdr
and $FF);
FRequestBuffer[4] := Byte(remainingBytes
and $FF);
SendBuffer(
TCP, RequestBuffer);
ReceiveBuffer(
TCP, FBuffer, sAdr, remainingBytes);
BufferToValues;
except
on e:
Exception do
begin
frmTCPLog.Add(FTCP.Host+'
Recovering from "'+e.
Message+'
"');
CreateTCP;
end;
end;
end;
Der Fehler der auftritt, ist der in diesem except-Block der zuletzt gezeigten Prozedur. Das heisst das bloße Connect geht, aber die Kommunikation führt zum Fehler. Aber halt nur bei einem Partner, und nach unbestimmter Zeit tadelloser Funktion.
Der Vollständigkeit halbar noch die Send- und RecieveBuffer Funktionen:
Delphi-Quellcode:
function TValueGroup.ReceiveBuffer(AClient: TIdTCPClient; var ABuffer: TBytes; aOffset, aLength: Integer): Boolean;
var
b: TBytes;
begin
Result := True;
try
SetLength(b, aLength);
FillChar(b[0], aLength, 0);
AClient.IOHandler.ReadBytes(b, -1, false);
Move(b[0], ABuffer[aOffset], aLength);
except
Result := False;
end;
end;
function TValueGroup.SendBuffer(AClient: TIdTCPClient; ABuffer: TBytes): Boolean;
begin
try
Result := True;
try
AClient.IOHandler.WriteBufferOpen;
AClient.IOHandler.Write(ABuffer);
AClient.IOHandler.WriteBufferFlush;
finally
AClient.IOHandler.WriteBufferClose;
end;
except
Result := False;
end;
end;
Der OnStatus-Handler loggt nur die Statusänderungen und unternimmt sonst nichts.
"When one person suffers from a delusion, it is called insanity. When a million people suffer from a delusion, it is called religion." (Richard Dawkins)