Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi idTCPClient.Connect + Timeout und Abbruch (https://www.delphipraxis.net/85413-idtcpclient-connect-timeout-und-abbruch.html)

glkgereon 26. Feb 2007 15:16

Re: idTCPClient.Connect + Timeout und Abbruch
 
also ich habe das ganze mal so probiert:

Delphi-Quellcode:
procedure TConnectThread.Execute;
begin
  FConnected:=False;
  FTCP.Connect(FHost,FPort);
  FConnected:=True;
end;
und dann
Delphi-Quellcode:
var CT: TConnectThread;
    T: Cardinal;
begin
  try
    CT:=TConnectThread.Create(True);
    CT.FreeOnTerminate:=True;
    CT.TCP:=Fidtcp;
    CT.Host:=Host;
    CT.Port:=Port;
    T:=GetTickCount+5000; //5s-Timeout
    CT.Execute;
    while (T-GetTickCount>0) and (not Fidtcp.Connected) do
      FOnSleep; //Application.Processmessages
    if not Fidtcp.Connected then raise EConnectException.Create(''); //Hats nicht geschafft
    CT.Terminate;
    FListeningThread.Resume;
  except
    raise EConnectException.Create('');
  end;
end;
Aber irgendwie ändert das nichts :-(

halinchen 26. Feb 2007 15:36

Re: idTCPClient.Connect + Timeout und Abbruch
 
Delphi-Quellcode:
var CT: TConnectThread;
    T: Cardinal;
begin
  try
    CT:=TConnectThread.Create(True);
    CT.FreeOnTerminate:=True;
    CT.TCP:=Fidtcp;
    CT.Host:=Host;
    CT.Port:=Port;
    T:=GetTickCount+5000; //5s-Timeout
    CT.Resume; //Nicht Execute, sondern Resume
    while not Thread.Terminated do //Ich weiß nicht ob Terminated global ist
    If (T-GetTickCount<0) AND (not CS.FConnected) then break; //Eventuell noch einen Boolean auf true setzen, damit du weißt das es nicht verbunden werden konnte.
    end;
    CT.Terminate;
    //FListeningThread.Resume; -> Ich weiß nicht was du damit machen willst.
  except
    raise EConnectException.Create('');
  end;
end;

Das exceute muss glaube ich resume sein. Und mit einem Thread auf eine Komponente, die nicht zum Thread gehört,direkt ist glaub ich kein guter Programmierstil.

Wenn ich mich nicht verschätzt habe müsste es so klappen

glkgereon 26. Feb 2007 15:42

Re: idTCPClient.Connect + Timeout und Abbruch
 
also der FListeningThread ist dazu da mitzubekommen wann mal was reinkommt vom Server.
das kann TIdTCPClient ja auch nicht :wall:

Delphi-Quellcode:
while Thread.Terminated do
    If (T-GetTickCount<0) AND (not CS.FConnected) then break;
kannst du mir das mal erklären?

also solange der Thread nicht läuft (abgeschossen wurde) laufen wir durch.
und wenn dann die Zeit abgelaufen ist und immer noch nicht connected wurde brechen wir ab.
die schleife macht doch eh nix, oder?

halinchen 26. Feb 2007 15:45

Re: idTCPClient.Connect + Timeout und Abbruch
 
Zitat:

Zitat von glkgereon
die schleife macht doch eh nix, oder?

Ähm... Da hast du Recht... :oops:

Habs verbessert.

glkgereon 5. Mär 2007 17:05

Re: idTCPClient.Connect + Timeout und Abbruch
 
Sooo, nach einigen Querelen nun der nächste Versuch....

Ein kleiner Bug oben (was zum schmunzeln...): (T-GetTickCount<0) ist immer False...Das Ergebnis ist ein Cardinal und Cardinals sind immer positiv *g*

naja, nun siehts so aus:
Delphi-Quellcode:
procedure TConnectThread.Execute;
begin
  Priority:=tpLower;
  FConnected:=False;
  try
    FTCP.Connect(FHost,FPort);
    FError:=nil;
  except
    on E: Exception do FError:=E;
  end;
  if FError<>nil then
    raise FError
  else
    FConnected:=True;
  Terminate;
end;


procedure TChatClient.Connect(Host: String; Port: Integer);
var CT: TConnectThread;
    T: Cardinal;
    TT: TThread;
begin
  try
    CT:=TConnectThread.Create(True);
    CT.TCP:=Fidtcp;
    CT.Host:=Host;
    CT.Port:=Port;
    T:=GetTickCount+5000;
    CT.Resume;
    while (not CT.Terminated) do
    begin
      FOnSleep;
      if (GetTickCount>T) or (Fidtcp.Connected) then Break;
      Sleep(50);
    end;
    CT.Free;
  except
    raise EConnectException.Create('');
  end;
end;
Das Problem: Der Thread läuft weiter. und weiter. und weiter.
Irgendwie müsste der Thread vor dem CT.Free abgeschossen werden. denn CT.Free free't ja nicht den Thread selbst (so scheint es mir zumindest).

vor TerminateThread() schrecke ich (bisher) noch etwas zurück... Gibt es eine andere möglichkeit?

halinchen 6. Mär 2007 13:46

Re: idTCPClient.Connect + Timeout und Abbruch
 
Zitat:

Zitat von glkgereon
Das Problem: Der Thread läuft weiter. und weiter. und weiter.
Irgendwie müsste der Thread vor dem CT.Free abgeschossen werden. denn CT.Free free't ja nicht den Thread selbst (so scheint es mir zumindest).

Ich würde bei dem Thread FreeOnTerminate auf True setzen. Und wenn die Zeit um ist, einfach die Schleife verlassen und eine Fehlermeldung bringen. Der Thread hört dann nicht auf, aber das Hauptprogramm läuft weiter. Und wenn der Thread fertig ist sollte der Thread den Speicher selbstständig freigeben. (Allerdings dürfstest du dann kein Free aufrufen.)

Wenn du in deinem Thread dann noch mehr machen lassen willst, als sich nur zu verbinden, kannst du am Ende deines jetzigen Codes eine Abfrage reinschreiben:
Delphi-Quellcode:
If Terminated then exit;
Und in der Schleife schreibst du:
Delphi-Quellcode:
    while (not CT.Terminated) do
    begin
      FOnSleep;
      if (GetTickCount>T) or (Fidtcp.Connected) then begin
          CT.Terminate;
          Break;
          end;
      Sleep(50);
    end;
    //CT.Free; -> kein Free da FreeOnTerminate
  except
halinchen

P.S. Hoffe diesmal ohne Fehler... :lol:

glkgereon 6. Mär 2007 14:24

Re: idTCPClient.Connect + Timeout und Abbruch
 
Soo, es funktioniert jetzt :-)

Ein weiteres Problem was sich gestellt hat ist folgendes:
Ich möchte ja einen TCPClient im Thread verbinden welcher danach im Programm selbst verwendet werden soll.
Ergo muss ich das selbe Objekt nehmen. Wenn ich nun das Objekt im Thread am ende Free'e ist es ja weg. Wenn ich es nicht Free'e habe ich einen potentiellen Speicherfresser.

Meine Lösung sieht nun wie folgt aus:

Delphi-Quellcode:
procedure TConnectThread.Execute;
begin
  Priority:=tpLower;
  FConnected:=False;

  try
    FTCP.Connect(FHost,FPort);
  except
  end;
  if FTimeOut then FTCP.Free;

  FConnected:=True;
end;

procedure TChatClient.Connect(Host: String; Port: Integer);
var CT: TConnectThread;
    T: Cardinal;
begin
  if Connected then Exit; //Schon Connected -> Raus
  CT:=TConnectThread.Create(True);
  CT.TCP:=TIdTCPClient.Create; //Init
  CT.Host:=Host;
  CT.Port:=Port;
  CT.TimeOut:=False;
  CT.FreeOnTerminate:=True;
  T:=GetTickCount+5000; //5 Sek warten
  CT.Resume;
  while (not CT.Terminated) do
  begin //Thread läuft noch
    FOnSleep; //Warten
    if (GetTickCount>T) or (CT.Connected) then Break;
    Sleep(50); //und nochmal warten
  end;
  if CT.Connected then
  begin //Verbunden -> Alles OK -> Client übernehmen
    Fidtcp:=CT.TCP;
  end
  else //Nicht verbunden -> Alles Doof -> Client killen & Exception werfen
  begin
    CT.TimeOut:=True;
    raise EConnectException.Create('');
  end;
end;

halinchen 6. Mär 2007 14:30

Re: idTCPClient.Connect + Timeout und Abbruch
 
Entweder du nimmst einen TCPClienten auf der Form und greift mit dem Thread darauf zu. (Ich weiß nicht ob das so gut ist.)

Oder du machst im Thread einen TCPClienten und auf der Form auch. Und wenn es sich verbunden hat, freest du den auf der Form und setzt die Adresse vom Form-TCPClienten auf die vom Thread-TCPClienten.
(Ähm... :gruebel: ich mein das so:
Delphi-Quellcode:
FormTCP := ThreadTCP;
Allerdings kein Ahnung ob das so durchführbar ist... :?: :?: :?:


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:07 Uhr.
Seite 3 von 3     123   

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