AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi TClientSocket verbraucht Ports (Fehler 10055)
Thema durchsuchen
Ansicht
Themen-Optionen

TClientSocket verbraucht Ports (Fehler 10055)

Ein Thema von spitzley · begonnen am 26. Jun 2005 · letzter Beitrag vom 3. Jul 2005
 
spitzley

Registriert seit: 4. Jan 2005
2 Beiträge
 
#3

Re: TClientSocket verbraucht Ports (Fehler 10055)

  Alt 3. Jul 2005, 12:43
Hallo Bernd !

Danke für Deine Antwort. Ich habe das Problem ähnlich Deinem Vorschlag gelöst:
Ein Retry-Counter verlangsamt dynamisch den Reconnect-Timer-Takt:

Delphi-Quellcode:
procedure TNetRouter.OnGateway1ReconnectServerTimer(Sender: TObject);
begin
  if FGateway1Activate and not(FGateway1Connected) then
    begin
      if FGateway1AutoReconnect then
        begin
          inc(FGateway1NoOfConnectRetries);
          CtrlDlg.NotifyGateway1Info(format('ReConnect %d',[FGateway1NoOfConnectRetries]), $0080FFFF);
          Gateway1TCPClientSock.Close;
          Gateway1TCPClientSock.Open;
        end;
      FGateway1ReconnectServerTimer.Enabled:=false;
      FGateway1ReconnectServerTimer.Interval:=FGateway1NoOfConnectRetries*ReconnectServerTimerIntervalFactor;
    end;
end;
Bei Connect-Mißerfolg startet der Error Handler den Timer erneut:

Delphi-Quellcode:
procedure TNetRouter.Gateway1TCPClientSockError(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
   ErrorCode := 0;

   case ErrorEvent of
     eeGeneral:
       //Der Socket erhielt eine Fehlermeldung, die in keine der folgenden Kategorien paßt.
       CtrlDlg.NotifyGateway1Info('ClErr:unbek. Fehler', $0080FFFF);
     eeSend:
       //Beim Schreiben der Socket-Verbindung trat ein Fehler auf.
       CtrlDlg.NotifyGateway1Info('ClErr:Schreibfehler', $0080FFFF);
     eeReceive:
       //Beim Lesen der Socket-Verbindung trat ein Fehler auf.
       CtrlDlg.NotifyGateway1Info('ClErr:Lesefehler', $0080FFFF);
     TErrorEvent(6),eeConnect:
       //Bei Client-Sockets bedeutet dieser Wert, daß der Server nicht gefunden
       //wurde oder daß ein Problem auf dem Server das Öffnen der Verbindung
       //verhindert. Bei Server-Sockets bedeutet dieser Wert, daß eine
       //Client-Verbindungsanforderung, die bereits angenommen wurde,
       //nicht beendet werden kann.
       begin
         CtrlDlg.NotifyGateway1Info('ClErr:Keine Verbindung', clRed);
         if Gateway1AutoReconnect and Gateway1ActivateTCPClient then
           FGateway1ReconnectServerTimer.Enabled:=true;
       end;
     eeDisconnect:
       begin
         //Beim Schließen einer Verbindung trat ein Fehler auf.
         CtrlDlg.NotifyGateway1Info('ClErr:Disconnect', clRed);
         if Gateway1AutoReconnect and Gateway1ActivateTCPClient then
           FGateway1ReconnectServerTimer.Enabled:=true;
       end;
   end;
end;
Das ganze funktioniert sowohl bei mißglückten Connects (Client-Verbindungsaufbau,aber Server nicht gefunden) als auch bei Disconnects (Server-Absturz).

Was ich nicht verstehe, ist Folgendes:

Der Server läuft an einem DSL-Anschluss mit dynamischer IP. Ändert sich jetzt die IP nach einigen Stunden, dann
gibts es beim Server ein "normales" Disconnect-Event und er trennt sich von seinen Clients.
Die Clients kriegen nichts vom IP-Wechsel mit und meinen weiterhin, sie seien verbunden.
(Es fließen keine Daten zum Server ! Das würde die Clients den Zusammenbruch merken lassen)

Delphi-Quellcode:
procedure TNetRouter.Gateway1TCPServSockClientDisconnect(Sender: TObject; Socket: TCustomWinSocket);
begin
  try
  FConnectedTCPClient:=ConnectedTCPClientBySocket(FGateway1ConnectedTCPClientList,Socket);
  RemoveConnectedTCPClient(FGateway1ConnectedTCPClientList,Socket);
  CtrlDlg.NotifyGateway1Info('Noch '+IntToStr(FGateway1ConnectedTCPClientList.Count)+' Teilnehmer', $0080FFFF);
  Log('GW1,TCP-Server,getrennt von '+Socket.RemoteAddress+':'+IntToStr(Socket.RemotePort));
  Gateway1Connected:=FGateway1ConnectedTCPClientList.Count<>0;
  except end;
end;
Es gibt kein Error-Event, wo ich in diesem Handler auf die ungewollte Trennung reagiern könnte:

Delphi-Quellcode:
procedure TNetRouter.Gateway1TCPServSockClientError(Sender: TObject; Socket: TCustomWinSocket;
  ErrorEvent: TErrorEvent; var ErrorCode: Integer);
begin
   ErrorCode := 0;
   case ErrorEvent of
     eeGeneral:
       //Der Socket erhielt eine Fehlermeldung, die in keine der folgenden Kategorien paßt.
       CtrlDlg.NotifyGateway1Info('SvErr:unbek. Fehler', $0080FFFF);
     eeSend:
       //Beim Schreiben der Socket-Verbindung trat ein Fehler auf.
       CtrlDlg.NotifyGateway1Info('SvErr:Schreibfehler', $0080FFFF);
     eeReceive:
       //Beim Lesen der Socket-Verbindung trat ein Fehler auf.
       CtrlDlg.NotifyGateway1Info('SvErr:Lesefehler', $0080FFFF);
     eeConnect:
       //Bei Client-Sockets bedeutet dieser Wert, daß der Server nicht gefunden
       //wurde oder daß ein Problem auf dem Server das Öffnen der Verbindung
       //verhindert. Bei Server-Sockets bedeutet dieser Wert, daß eine
       //Client-Verbindungsanforderung, die bereits angenommen wurde,
       //nicht beendet werden kann.
       CtrlDlg.NotifyGateway1Info('SvErr:Verbindungsaufbau', $0080FFFF);
     eeDisconnect:
       begin
         //Beim Schließen einer Verbindung trat ein Fehler auf.
         RemoveConnectedTCPClient(FGateway1ConnectedTCPClientList,Socket);
         CtrlDlg.NotifyGateway1Info('SvErr: Noch '+IntToStr(FGateway1ConnectedTCPClientList.Count)+' Teilnehmer', $0080FFFF);
       end;
     eeAccept:
       //Beim Übernehmen einer Client-Verbindungsanforderung trat ein Fehler auf (nur bei Server-Sockets).
       CtrlDlg.NotifyGateway1Info('SvErr:Verb.anford.', $0080FFFF);
   end;
end;
Warum gibts da kein Event bei den Clients ?

Mein WorlAround wäre: Die Clients prüfen periodisch per DNS-Resolving, ob die Server IP sich geändert hat.

Delphi-Quellcode:
function GetIPAddressByDNSQuery(URL, DNSServer : string):string;
var
  IdDNSResolver: TIdDNSResolver;
  I: Integer;
begin
  Result:='';
  IdDNSResolver:=TIdDNSResolver.Create(nil);

  IdDNSResolver.ReceiveTimeout:=6000; //6 Sekunden bis zum Timeout !!!!!

  IdDNSResolver.Host := DNSServer;
  try
    IdDNSResolver.Active := True;
    try
      IdDNSResolver.QueryResult.Clear;
      IdDNSResolver.QueryRecords := [qtSTAR];
      IdDNSResolver.Resolve(URL);
      if IdDNSResolver.QueryResult.Count<>0 then
      for I := 0 to IdDNSResolver.QueryResult.Count-1 do
      begin
        case IdDNSResolver.QueryResult.Items[I].RecType of
        qtA:
          begin
            Result:=TARecord(IdDNSResolver.QueryResult.Items[I]).IPAddress;
            break;
          end;
        end;
      end;
    except
    end;
  finally
    IdDNSResolver.Active := False;
    IdDNSResolver.Free;
  end;
end;
Das erscheint mir aber aufwendig und unelegant.

Wie sonst können nichtsendende Clients den Kontaktverlust zum Server bemerken ?

Idee ?


Grüße

Kurt Spitzley
  Mit Zitat antworten Zitat
 


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