Delphi-PRAXiS

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)

halinchen 30. Jan 2007 14:18


idTCPClient.Connect + Timeout und Abbruch
 
Hallo,

ich habe einen TidTCPClient zur Laufzeit erzeugt und initialisiert.
Wenn ich nun den Clienten mit dem Server connecten will und den Server gibt es nicht, dauert es 15 Sekunden bis es abbricht.
Und dabei ist es egal ob ich als Parameter (also TimeOut) 1 oder 99999 übergebe.

Delphi-Quellcode:
Client.Connect(1);
//Selbe Zeit auch bei
Client.Connect(99999);
Ich will aber das der Nutzer festlegen kann wann es abbricht, oder geht es gar nicht da es dort wichtige Prozesse ausführt?

Außerdem möchte ich auch noch einen Abbruch-Button auf die Form bringen und bei Klick soll es das Connecten abbrechen.

Ich hoffe ihr versteht mich :oops:.

halinchen

Lun 30. Jan 2007 14:22

Re: idClient.Connect + Timeout und Abbruch
 
Hi ,

ich weiß zwar nicht was du mit idclient meinst. aber bei meinem idhttp clienten funtzt das so:

idhttp.ConnectionTimeout(5); 5 der Wert wann er den Versuch des Verbindungsaufbau abbrechen soll. Standardwert ist 15

greetz Lun

halinchen 30. Jan 2007 14:31

Re: idTCPClient.Connect + Timeout und Abbruch
 
Hi!

Danke für die schnelle Antwort. :mrgreen:
Das TidClient muss TidTCPClient heißen. Sorry :oops: :oops: :oops:

Da hab ich das falsch verstanden! Ich dachte TimeOut es gibt eine Zeitspanne an!
In der Hilfe von Indy hab ich das nicht kapiert. :wall: :wall: :wall:
Danke!

halinchen

Lun 30. Jan 2007 14:43

Re: idTCPClient.Connect + Timeout und Abbruch
 
Hi ,

öhm jetzt bin ich selber verwirrt :gruebel:

wie komme ich auf 15 sekunden ???
Also du hast schon recht es handelt sich dabei um eine Zeitspanne.

ConnectTimeout is an Integer property published in TIdTCPClient. ConnectTimeout indicates the number of milliseconds to wait for successful completion of a connection attempt for the client.
The default value for ConnectTimeout is 0, and indicates that the default timeout value for the protocol stack implementation should be used when establishing the client connection.

greetz Lun

Aufjedenfall kann ich durch den Aufruf .ConnectionTimeout(integer) die Zeitspanne beinflussen in der eine Verbindung zu stande kommen sollte.

halinchen 30. Jan 2007 14:53

Re: idTCPClient.Connect + Timeout und Abbruch
 
Schon wieder was falsch verstanden!!! :wall:
Puh, schlechter Tag heut :? !

Also habe ich ja theoretisch keinen Fehler gemacht.
Aber ich kann da bei TimeOut angeben was ich will, es macht irgentwie keine Unterschied.
Jetzt weiß ich aber das ich nichts falsch mache.
Naja, kann man scheinbar nichts machen und ich muss damit leben.

Danke das du dich so bemüht hast mir das beizubringen!!! :cheers:

halinchen

Lun 30. Jan 2007 15:09

Re: idTCPClient.Connect + Timeout und Abbruch
 
Kein Problem :wink:

hmm sorry wenn das jetzt ne Blöde frage ist :

Aber du schreibst nicht client.Connet(5) oder so oder? Wie oben im ersten post.

Sondern tcpclient.ConnectionTimeout := 5;

und es funtzt nicht?

Merkwürdig :roll:

Naja, vielleicht weiß jemand anders ja noch Rat.

greetz Lun

halinchen 30. Jan 2007 15:32

Re: idTCPClient.Connect + Timeout und Abbruch
 
Zitat:

Zitat von Lun
Aber du schreibst nicht client.Connet(5) oder so oder? Wie oben im ersten post.

Sondern tcpclient.ConnectionTimeout := 5;

Ich muss client.Connect(5), da es client.ConnectionTimeout gar nicht gibt.
In der Indy Hilfe wird es nie erwähnt (auch nicht im Index) und Delphi akzeptiert es auch nicht.

Indy Hilfe:
Delphi-Quellcode:
procedure TidTCPClient.Connect(const ATimeout: Integer = IdTimeoutDefault); virtual;
-> Besagt ja das der Parameter der TimeOut-Wert ist.

Achso: Ich nutze Indy 9

Lun 30. Jan 2007 15:39

Re: idTCPClient.Connect + Timeout und Abbruch
 
Achso :wink: ,

Zitat:

Achso: Ich nutze Indy 9
das erklärt einiges ich benutze indy 10, und da gibt es den connection timeout für den tcpclienten. Daher auch der eintrag der Hilfe
den ich gepostet habe.
Und da funtzt das so wie ich es beschrieben habe ;O)

Naja, also alle indy 9er auf die Matte, da muss es doch ne möglichkeit geben.

greetz Lun

Klaus01 30. Jan 2007 15:57

Re: idTCPClient.Connect + Timeout und Abbruch
 
tut sich etwas wenn Du diesen Timeout setzt?

Delphi-Quellcode:
idTcpClient1.ReadTimeout:=
Grüße
Klaus

halinchen 30. Jan 2007 16:05

Re: idTCPClient.Connect + Timeout und Abbruch
 
Danke für die Antworten!

Zitat:

Zitat von Klaus01
tut sich etwas wenn Du diesen Timeout setzt?

Delphi-Quellcode:
idTcpClient1.ReadTimeout:=

Leider nein.
Ich setzte vor dem Connecten diesen Wert bereits auf den selben wie bei Client.Connect.
Ich installier jetzt Indy 10, mal sehen was es bringt.

Klaus01 30. Jan 2007 16:07

Re: idTCPClient.Connect + Timeout und Abbruch
 
Hallo,

habe noch folgenden Thread in den NewsGroups gefunden: http://groups.google.de/group/borlan...2020fea855b604

Erklärt vielleicht das Problem.

Und viel Erfolg mit den 10er Indys.

Grüße
Klaus

halinchen 30. Jan 2007 16:10

Re: idTCPClient.Connect + Timeout und Abbruch
 
Danke!
Ich denke es ist genau das was ich suche! :party:

halinchen 30. Jan 2007 16:52

Re: idTCPClient.Connect + Timeout und Abbruch
 
Ich hab jetzt Indy 10 installiert.

Und es geht nicht... :cry:

"Fehler beim Laden von Client.ConnectionTimeOut, Eigenschaft existiert nicht".

Übrigens auch bei einem, außer einem TidTCPClient, komplett leeren Projekt.
Ich probiers erstmal zu beheben, sonst kann ich schlecht weitermachen :wink:

inherited 30. Jan 2007 17:01

Re: idTCPClient.Connect + Timeout und Abbruch
 
Hast du die Pfade gesetzt?

halinchen 30. Jan 2007 17:05

Re: idTCPClient.Connect + Timeout und Abbruch
 
Ja. Ich habe selbst alle (und wirklich alle) Packages in Delphi deinstalliert und die *.bpl Dateien gelöscht. Und musste ich ich alles Packages wieder installieren.

Ich nehm jetzt wieder Indy 9, da gibts auch den TidICMPClienten.
Dann steig ich um wenn ich Zeit habe.

EDIT:
Zitat:

Set TIdICMPClient.Host to the Host IP to be checked.
Set TIdICMPClient.ReceiveTimeout to the number of ms to wait.
Call TIdICMPClient.Ping.
Check TIdICMPClient.ReplyStatus.ReplyStatusType.

If the ReplyStatus.ReplyStatusType <> rsTimeOut then it should be safe to
call Connect using the TCP Client. Otherwise connect will block until the
protocol stack times out.
Ich habs genauso gemacht und die CPU-Auslastung ging auf 100%, sonst passiert nichts. Nach ICMP.Ping ist Schluss;
Nach 2 Minuten hab ich es aufgegeben.
Das hatte es allerdings in einem Thread gemacht.

Ohne Thread funktioniert es!
Auf der Seite schien es bei ihm aber zu klappen, nur bei 2 gleichzeitigen nicht.

Hier mein Code:
Delphi-Quellcode:
var
ICMP:TidICMPClient;
begin
ICMP := TidICMPClient.Create(NIL);
ICMP.Host := Host; //Host, Port, TimeO sind globale Variablen des Thread-Objekts
ICMP.Port := Port;
ICMP.ReceiveTimeout := TimeO;
try
ICMP.Ping;
except
... //Hier Thread beenden
ICMP.Free;
exit;
end;
ICMP.Free;
...
end;
halinchen

P.S. Man muss nicht den ReplyStatus.ReplyStatustype abfragen, sondern den Ping-Befehl in einen try...except...end-Block (zumindest ging es bei mir nur so).

halinchen 1. Feb 2007 13:09

Re: idTCPClient.Connect + Timeout und Abbruch
 
Ich hab jetzt alles mit Indy 10 getestet. Auch kein Unterschied.
Ich werde die Sache jetzt auf sich beruhen lassen. Ich mach es ja nur als Hobby und ich hätte nie gedacht das sowas so kompliziert ist! :shock:

Nochmal ein dickes "DANKE" an alle! :thumb:

halinchen

P.S. Falls ich trotzdem mal rausfinde worin es lag, schreib ich es hier rein. :coder:

halinchen 7. Feb 2007 12:29

Re: idTCPClient.Connect + Timeout und Abbruch
 
Ich hab mir das alles nochmal angeguckt. :shock:
Die Ping-Indy Kompo braucht irgentwelchen RAW-Zugriff.
-> Man muss Admin sein.

Kennt jemand eine Ping-Komponente, mit der man auch als eingeschränkter Benutzer pingen kann?

halinchen 14. Feb 2007 11:37

Re: idTCPClient.Connect + Timeout und Abbruch
 
Für alle die das selbe Problem wie ich haben:
Mit den TimeOut Funktionen der einzelnen Kompos kommt man nicht weiter. :?
Aber es geht doch: :lol:

Ich habe mir einen Thread angelegt, der das Senden übernimmt.
Nun habe ich vor dem Aufrufen des Threads GetTickCount in eine Variable gespeichert.
Und nun in einer Schleife testen ob die Zeit überschritten ist
Delphi-Quellcode:
Tick := GetTickCount;
While (not thread.Terminated) do begin
    Application.ProcessMessages;
    If (GetTickCount-Tick > TimeOut) AND (not thread.state) then break;
    end;
Nochmal zur Erläuterung:
thread.state ist ein Boolean und wird nach dem Verbinden (Client.Connect im Thread.Execute-Teil) auf true gesetzt.
Das habe ich gemacht, das es nicht abbricht wenn es sich schon verbunden hat. Es kann ja sein das das senden etwas länger dauert. :???:

halinchen

//EDIT: Thread.FreeOnTerminate muss True sein, sonst gibt es den Speicher nicht mehr frei!!!

glkgereon 26. Feb 2007 09:07

Re: idTCPClient.Connect + Timeout und Abbruch
 
Ich stehe vor dem selben Problem...

Es kann doch nicht sein dass man um ein ConnectTimeout abzufangen in einem neuen thread anfangen muss den server zu pingen :roll:

Ich mein: ignoriert der IdTCPClient die Eigenschaft "ConnectTimeout" einfach?
Ist doch echt zum heulen :cry:

*anfang thread zu schreiben*

wenn irgendwer noch eine andere Idee hat...hierhin :-)

halinchen 26. Feb 2007 12:35

Re: idTCPClient.Connect + Timeout und Abbruch
 
Du kannst auch unter der Eingabeaufforderung "ping computer /w 1" und "ping computer /w 1000". Da kommt auch kein Unterschied :wink: .

Wenn du Hilfe brauchst kannst mich ja auch fragen. Ist eigentlich auch nicht schwerer. Wenn du willst zeig ich dir den ganzen Quelltext.

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 16:56 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