Einzelnen Beitrag anzeigen

Medium

Registriert seit: 23. Jan 2008
3.686 Beiträge
 
Delphi 2007 Enterprise
 
#3

AW: Socket Error 10054 Connection reset by peer - wie behandeln?

  Alt 5. Nov 2015, 16:47
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)

Geändert von Medium ( 5. Nov 2015 um 16:59 Uhr)
  Mit Zitat antworten Zitat