Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi TIdTCPServer / TIdTCPClient => Ping - Pong (https://www.delphipraxis.net/152393-tidtcpserver-tidtcpclient-%3D-ping-pong.html)

Jackie1983 21. Jun 2010 12:15

TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi,

bei meiner Anwendung muss immer eine Verbindung mit dem Server bestehen. Habe das früher mit den Sockets gemacht, da hat es so funktioniert. Jetzt wo ich das mit den Indys mache und alles auf Threads basiert, weis ich nicht ob das immer noch so funktionieren würde.

Das ist der Client Execute, gekürzt.
Delphi-Quellcode:
  while not Terminated do begin
    if not fClient.Connected then
      try
        fClient.Connect(1000);
      except
      end;

    //Ping senden
    if fClient.Connected then begin
      cmd := TCommandHandling.Create(CMDPing);
      try
        fClient.WriteLn(cmd.SendFrames);
        msg := fClient.ReadLn; //Antwort cmdPong
      except
        fClient.Disconnect; //Timeout, kein Pong bekommen.
      end;
    end;

    //Text empfangen
    if fClient.Connected then begin
      try
        try
          IsTimeout := false;
          msg := fClient.ReadLn;
        except
          IsTimeout := True;
        end;

        if not IsTimeout then begin
          cmd := TCommandHandling.Create(CMDNone);
          try
            cmd.SetFrames(msg);
            try
              if Assigned(fOnRead) then
                fOnRead(cmd);
            except
              //Fehler in OnRead abfangen
            end;
          finally
            FreeAndNil(cmd);
          end;
        end;
      finally
        fCS.Leave;
      end;
    end;
    sleep(100);
  end;
Und der Server -> OnRead
Delphi-Quellcode:
  AThread.Connection.ReadTimeout := 1000;

  fCS.Enter;
  try
    try
      msg := AThread.Connection.ReadLn;
    except
      exit;
    end;
  finally
    fCS.Leave;
  end;

  cmd := TCommandHandling.Create(CMDPong);
  try
    cmd.SetFrames(msg);
    if cmd.GetCmd = CMDPing then
      AThread.Connection.WriteLn(cmd.SendFrames) //Pong senden
    else begin //rest weiter geben
      if Assigned(fOnRead) then
        fOnRead(AThread, cmd);
    end;
  finally
    FreeAndNil(cmd);
  end;
Soweit funktioniert der Test bei 2 Computer. Gibt es noch was wo drauf ich achten muss oder eventuell was ich besser machen kann.

Mfg

Jackie1983 21. Jun 2010 13:03

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Ok so wie ich es jetzt gemacht habe geht es nicht.
Habe im Client einfach per Timer text gesendet und im Server den Text einfach wieder zum Client zurück gesendet. Da kommt nur alle paar Sekunden was an, wenn überhaupt.

Irgend wo habe ich da noch einen Fehler....

//Edit
Nach einer Zeit friert der gesamte Client ein. Habe jetzt den Text am Client mal nicht in der Listbox angezeigt und so funktioniert es. So sehe ich nicht ob Text angekommen ist, müste schon, aber die Anwendung läuft weiter...

So schwer bzw. anders kann es doch gar nicht sein....

DataCool 21. Jun 2010 13:31

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi Jackie,

1. Wozu soll die CriticalSection im OnExecute des Server sein(hoffe Du meinst OnExecute, denn geschrieben hast Du OnRead) Deine var msg, solltest Du einfach lokal im OnExecute deklarieren.
2. Sollte Dir bewußt sein, das das OnExecute des Servers andauerd hintereinander aufgerufen wird(solange wie Client verbunden ist), so kann es auch mal passieren das DEin AThread.Connection.ReadLn; nichts(Lerrstring) zurück liefert, diesen Fall solltest Du abfangen und nicht Dein Event feuern.
3. Sollte es ein Kommando für das saubere Abmelden des Clients geben, z.B. Client sendet "QUIT", Server und Client trennen danach die Verbindung sauber.
4. Benutzt Du noch die 9er Version der Indys, das an sich ist kein Problem ich habe auch noch ein paar Projekte damit laufen, generell sollte man aber bei Neuentwicklungen jetzt auf die 10er Version setzen.

Greetz Data

Jackie1983 21. Jun 2010 13:47

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi DataCool,

also....
Zitat:

Zitat von DataCool (Beitrag 1030631)
1. Wozu soll die CriticalSection im OnExecute des Server sein(hoffe Du meinst OnExecute, denn geschrieben hast Du OnRead) Deine var msg, solltest Du einfach lokal im OnExecute deklarieren.

Die CS ist damit wenn der Server gerade list nicht wo anders am Server OnWrite aufgerufen wird. Oder ist das CS zu viel, habe das gleich auch am Client.
Habe die Funktion nur OnRead genannt. msg ist local.

Zitat:

Zitat von DataCool (Beitrag 1030631)
2. Sollte Dir bewußt sein, das das OnExecute des Servers andauerd hintereinander aufgerufen wird(solange wie Client verbunden ist), so kann es auch mal passieren das DEin AThread.Connection.ReadLn; nichts(Lerrstring) zurück liefert, diesen Fall solltest Du abfangen und nicht Dein Event feuern.

Ein leerstring sollte eigentlich nicht kommen. Und wenn doch kann ich eh nichts damit anfangen. Also bei einem fehler, meist Timeout, soll nicht weiter gemacht werden, falsch?

Zitat:

Zitat von DataCool (Beitrag 1030631)
3. Sollte es ein Kommando für das saubere Abmelden des Clients geben, z.B. Client sendet "QUIT", Server und Client trennen danach die Verbindung sauber.

Habe ich, nur wenn das Kabel gezogen wird muss der Server und der Client das ja auch mitbekommen und die verbindung trennen und wieder aufbauen.

Zitat:

Zitat von DataCool (Beitrag 1030631)
4. Benutzt Du noch die 9er Version der Indys, das an sich ist kein Problem ich habe auch noch ein paar Projekte damit laufen, generell sollte man aber bei Neuentwicklungen jetzt auf die 10er Version setzen.

Ja benutze die 9er. Hmm ok dann werde ich mal die 10er suchen und installieren. Denke dazu muss ich die 9er komplett löschen?

Mfg

DataCool 21. Jun 2010 14:08

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
HI Jackie,

1.
Zitat:

Die CS ist damit wenn der Server gerade list nicht wo anders am Server OnWrite aufgerufen wird. Oder ist das CS zu viel, habe das gleich auch am Client.
Habe die Funktion nur OnRead genannt. msg ist local.
Die CS solltest Du auf jeden Fall rausschmeissen, im Client kann das sinnvoll und notwendig sein. Im Server allerdings läuft jedes OnExecute(bei Dir OnRead) innerhalb eines eigenen Threads und wenn sdie Variable "msg" sowieso lokal ist, gibt es keinerlei GRund diese mit einer CS zu schützen ,auf jeden Fall sehe ich keinen auf Basis der Codeschnipsel.

2.
Zitat:

Ein leerstring sollte eigentlich nicht kommen. Und wenn doch kann ich eh nichts damit anfangen. Also bei einem fehler, meist Timeout, soll nicht weiter gemacht werden, falsch?
Recht hast Du, ich war mit meiner etwas zu voreilig, das liegt allerdings dran das ich das ganze immer ohne Exception löse.
In Indy10 würde das dann so aussehen :
Delphi-Quellcode:
  // Bis max. 2,5 Sekunden warten das Daten erfolgreich in den Buffer geschrieben wurden
  AContext.Connection.IOHandler.CheckForDataOnSource(2500);
  // Prüfen, ob die Client Verbindung noch besteht, eventuell hat der Server beim CheckForDataOnSource festgestellt das die Verbindung weg ist
  if not AContext.Connection.Connected then exit;
  // Sind keine Daten im Buffer, dann raus
  if AContext.Connection.IOHandler.InputBufferIsEmpty then exit;
  // hier jetzt weiter mit ReadLN ... sind jetzt auf jeden Fall Daten zum Lesen da !
  // ...
In Indy9 sollte der Code auch funktionieren Du must nur AConntext durch AThread ersetzen und das IOHandler in der Mitte weg lassen.

3. Ok, dann ist ja alles gut ;-)

4. Zur Umstellung von Indy9 auf Indy10 existieren hier einige Threads, das ganze ist je nach Delphi Version mit ein bisschen "Handarbeit" verbunden. Deshalb hängt es von der größere des Projekts und DEiner aktuellen Entwicklungsumgebung ab ob es jetzt wirklich ratsam ist auf Indy10 umzustellen,
oder ob für Deine Belange Indy9 absolut ausreichend ist. Eine großere Änderung von Indy9 zu Indy10 ist, das nicht mehr jede Connection Ihren eigenen Thread hat,
sondern das es einen "Thread-Pool" gibt, der freie Threads an die verschiedenen Clients verteilt.

Greetz Data

Jackie1983 21. Jun 2010 14:41

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
ok bin schon dabei die 10er zu installieren, weil wenn ich das schon neu mache dann kann ich auch die 10 nehmen. Habe bei der Installation schon einige Probleme. Die Demos funktionieren nicht, es können eigenschaften nicht gefunden werden so wie ganze units, obwohl ich die alles gesetzt habe.

Habe es nach dieser Anleitung gemacht
http://www.indyproject.org/Sockets/D...lation.de.aspx

DataCool 21. Jun 2010 14:53

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi,

da gibt es hier im Forum weitaus genauere Anleitungen,
ganz entscheided für die Sache ist allerdings,
welche Delphi-Version Du benutzt ?!
Und auch welche Indy-Version Du Dir gezogen hast ?!
Die ist nämlich im Moment gespalten, empfehle Dir den "Tiburon-Branch" empfehlen.

Greetz Data

Jackie1983 21. Jun 2010 15:09

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Habe Delphi 2007 Enterprise.
Oh, da gibt es auch noch mehrere Versionen.
Von wo bekomme ich die?

DataCool 21. Jun 2010 15:21

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi,

schau mal hier.

Greetz Data

P.S.: Bei Delphi2007 sollten eigentlich die Indy in einer frühen Version der 10er(10.1.5 oder 10.2.3) mit dabei sein, bin mir eigentlich ziemlich sicher, frage mich wie Du zu Indy9 kommst.

Jackie1983 21. Jun 2010 15:33

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi,

danke für den Link.
Ist die Reihenfolge jetzt anders bei der Installation wie oben
in der Anleitung?:stupid:
Gute frage, ich weis es nicht...

//Edit
Habe das ganze jetzt wie folgt installiert
Zitat:

Path Run-time Package Design-time Package
.\System IndySystem70.dpk n/a
.\Core IndyCore70.dpk dclIndyCore70.dpk
.\Protocols IndyProtocols70.dpk dclIndyProtocols70.dpk

.\SuperCore IndySuperCore70.dpk dclIndySuperCore70.dpk
Dann habe ich mir die Demos von der Seite geladen. Wollte die Anwendung Chat2.0 testen.
Fehler, datei IdCoreGlobal nicht gefunden....

DataCool 21. Jun 2010 15:49

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi,

ich denke Du must noch in Delphi unter "Tools\Optionen" den Bibliotheks-/Suchpfad setzen.

Greetz Data

Jackie1983 21. Jun 2010 15:56

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Ne die Datei gibt es ja nicht bei mir auf dem Computer, habe ja danach gesucht.
Mein Projekt scheint aber noch zu funktionieren. Muste eigentlich nichts umstellen.
Hoffe das ich das jetzt richtig installiert habe.

Danke für deine Hilfe. Werde mal schauen wie weit ich komme...
{Edit} Der Client friert dennoch ein :(, zum ko....{/Edit}
{Edit} Wenn ich am Client das CS rausnehme kein Problem, irgend wo habe ich noch ein kleine Problem, naja....{/Edit}
Mfg

DataCool 21. Jun 2010 16:29

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi Jackie,

dann poste nochmal Deinen jetzt aktuellen Code,
Indy arbeitet übrings mit Blocking-Sockets,
deshalb solltest Du Deinen "Client-Code" in einen Thread auslagern
oder zumindest ein TIdAntiFreeze auf Deine Main-Form ziehen und
die Eigenschaft "ApplicationHasPriority" auf true setzen.

Greetz Data

Jackie1983 21. Jun 2010 16:35

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
hi,

ok wenn das nicht zu viel ist, mache ich das gerne.
Ist alles im Thread :D

Client Send
Delphi-Quellcode:
  if not fclient.Connected then exit;

//  fcs.Enter;
  try
    try
      fClient.WriteLn(ACmd.SendFrames);
    except
    end;
  finally
//    fcs.Leave;
  end;
Client Execute
Delphi-Quellcode:
  fClient := TIdTCPClient.Create(nil);
  fClient.ReadTimeout := 500;
  fClient.Host := fHost;
  fClient.Port := FPort;

  while not Terminated do begin
    //Prüfen ob Client Online
    if not fClient.Connected then
    begin
      try
        fClient.Connect(500);
      except
        //beep;
      end;
    end;

    //Ping senden
    (*
    if fClient.Connected then begin
      cmd := TCommandHandling.Create(CMDPing);
      try
        fCS.Enter;
        try
          fClient.WriteLn(cmd.SendFrames);
          msg := '';
          msg := fClient.ReadLn;
        finally
          fCS.Leave;
        end;
        if msg = '' then
          fClient.Disconnect;
      except
        fClient.Disconnect;
      end;
    end;
    *)

    //Text empfangen
    if fClient.Connected then begin
//      fCS.Enter;
      try
        try
          IsTimeout := true;
          msg := fClient.ReadLn;
          IsTimeout := false;
        except
          //Timeout
          IsTimeout := True;
        end;

        if not IsTimeout then begin
          cmd := TCommandHandling.Create(CMDNone);
          try
            cmd.SetFrames(msg);
            try
              if Assigned(fOnRead) then
                fOnRead(cmd);
            except
              //Fehler in OnRead abfangen
            end;
          finally
            FreeAndNil(cmd);
          end;
        end;
      finally
//        fCS.Leave;
      end;
    end;
    sleep(100);
  end;

Jackie1983 21. Jun 2010 18:07

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
So nach dem ich jetzt schon den ganzen Tag am test bin und einfach nicht weiter weis.... Möchte ich das ganze mal beschreiben, vielleicht mach ich im Ansatz was falsch.

Ziel des Projektes ist es ein einfachen Server / Client zubekommen der Text über das Netzwerk sendet, später noch mit SSL. Die Clients müssen überwacht werden und sobald eine Verbindung nicht stimmt, muss der Server die Verbindung trennen und der client die Verbindung neu aufbauen.

Der Server / TIdTCPServer.
- Der Server läuft in einem Thread.
- Im Execute vom Thread werden die Vars erstellt und eine While
not Terminated Schleife mit sleep(100).
- Im OnExecute vom Server werden die Daten mit ReadLn und einem Timeout (500)
gelesen. Wenn Daten da sind. Daten in Befehl umwandeln. Wenn Befehl Ping sende
Pong zurück, wenn andere Daten an fOnRead weitergeben zum verarbeiten.
- Es wird kein CriticalSection verwendet.
- Methode OnTimeAlive, hier prüft der Server anhand
einer Liste welche Clients online sind, wenn Client nicht auf Ping antwortet,
Verbindung trennen.

Der Client / TIdTCPClient
- Der Client läuft als Thread.
- Execute vom Thread: prüfen ob Client Online ist, wenn nicht anmelden.
- Execute vom Thread: Daten da, wenn nein exit, wenn ja Daten weiter an fOnRead geben
- Methode Send. Sendet Daten an Server. Erst ein Ping senden und auf ein Pong warten,
wenn Pong ok, dann Daten senden, wenn nicht exit und Verbindung neu aufbauen.
- Es wird kein CriticalSection verwendet.
- Per Timer sendet der Client zum Test einen String zum Server.

Soweit so gut, aber irgend wie komme ich noch wo durcheinander so das mein Client einfriert.

(Noch ne frage, bei den Sockets habe ich die Befehle in einer Jobliste verarbeitet, heist wenn ein job nur halb gesendet wurde, wird gewartet bis dieser ganz da ist und erst dann weiter gegeben, wie ist das bei den Indys. Muss ich mich auch drum kümmern, wenn ein Befehl zu groß ist das dieser auch ganz ankommt?
Glaube das mit den Indy Threads habe ich noch nicht ganz verstanden :( )

Mfg

DataCool 22. Jun 2010 11:14

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi Jackie,

der Source-Code im Posting davor lässt "leider" noch ganz klar darauf schliessen das Du Indy9 verwendest,
was auch nicht schlimm ist, Dein Problem bekommst Du mit Indy9 oder Indy10 gelöst.
Wie Du allerdings am besten von Indy9 auf Indy10 umstellst, kann Du hier nachlesen, achte besonders auf Assertot's Antwort.

Unabhängig davon nochmal zu Deinem Problem, wenn ich ein wenig Luft hätte würde ich Dir ja ne kleine Demo mit Client & Server schreiben.
Allerdings ist ist bei mir im Moment alles andere mehr verfügbar als Zeit :roll:

Nochmal zum vorgehen, der Client sollte wie von Dir auch schon genannt in einem eigenen Thread laufen.
Der Server(egal ob Indy9/Indy10) behandelt alles intern schon in Threads, Du brauchst KEINE(N) extra Thread(s) erzeugen.
DU DARFST AUF KEINEN FALL EINE SCHLEIFE INS ONEXECUTE DES SERVERS BAUEN !
Das OnExecute läuft selber schon in der Schleife eines Indy internen Threads,
d.h. solange der Client connected ist tritt immer wieder das OnExecute ein !!

Deine "Jobliste" brauchst Du bei Indy nicht, das behandeln die alles intern,
ReadLn liefert erst Daten zurück wenn auch ein CRLF angekommen ist.

Ich denke Dein Fehler liegt im Servercode, kannst Du denn nicht komplett posten ?

Greetz Data

Jackie1983 22. Jun 2010 11:30

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi Data,

danke erst mal das du dir die Zeit nimmst das ganze mit mir durchzugehen.
Eventuell noch als Hinweis. Die Befehle die versendet werden sehen so aus.
Delphi-Quellcode:
  TSocketPaket = record
    //Header
    sizeGesamt : integer;
    sizeDaten : integer;
    Command : TCommand;
    //Daten
    daten : TStringlist;
  end;

function TCommandHandling.SendFrames: String;
var
  datastring,
  FFrames : string;
  size : integer;
begin
  datastring := fSocketPaket.daten.CommaText;

  //4 = Integer / Geaamtlänge
  //4 = Integer / Befehl
  //4 = Integer / Länge Daten
  //  = 12
  SetLength(FFrames,12+Length(datastring));
  ZeroMemory(Pchar(FFrames),Length(FFrames));

  //1-4  -> gesamtlänge
  PCardinal(@FFrames[1])^ := Length(fframes); //gesamtlänge
  //5-8  -> befehl
  PCardinal(@FFrames[5])^ := Integer(fSocketPaket.Command);
  //9-12 -> länge daten
  PCardinal(@FFrames[9])^ := Length(datastring);

  //13-x -> daten
  size := length(datastring);
  if datastring <> '' then
    System.Move(Pchar(datastring)^,Pointer(@FFrames[13])^,Size);

  result := FFrames;
end;
Denke werde es aber so machen wie ich hier im Beispiel gefunden habe.

Also so in der Art. Starte Kommunikation, warte auf antwort, sende Daten, warte auf Antwort, sende Daten, ...., beende Kommunikation. Warte auf Kommunikation Start...

Das ist der Server.
Delphi-Quellcode:
unit DTS_Server;

interface

uses
  Windows, Classes, IdTCPServer, SysUtils, DTS_Command, DTS_Utils,
  IdSocketHandle, SyncObjs, Contnrs;

Type
  TServerOnRead = Procedure(AThread: TIdPeerThread; Data : TCommandHandling) of object;
  TServerOnEvent = Procedure(AThread: TIdPeerThread) of object;

  TClientData = class(TObject)
  private
    fDNS        : String;               { Hostname }
    fConnected,                          { Time of connect }
    fLastAction : TDateTime;            { Time of last transaction }
    fThread     : Pointer;              { Pointer to thread }
  public
    Property DNS : String read fDNS write FDNS;
    Property Connected : TDateTime read fConnected write fConnected;
    Property LastAction : TDateTime read fLastAction write fLastAction;
    Property Thread : Pointer read fThread write fThread;
  end;

  TDTSServer = class(TThread)
  private
    fPort : Integer;
    fClientList : TobjectList;
    fServer : TIdTCPServer;
    fOnRead : TServerOnRead;
    fOnDisconnect : TServerOnEvent;
    fBindIP : String;
    Procedure OnExecute(AThread: TIdPeerThread);
    Procedure OnConnect(AThread: TIdPeerThread);
    Procedure OnDisconnect(AThread: TIdPeerThread);
  public
    Constructor Create(Port : integer; BindIP : String = '127.0.0.1');
    Destructor Destroy; override;

    Procedure Broadcast(Data : TCommandHandling);
    Property OnClientReadData : TServerOnRead read fOnRead write fOnRead;
    Property OnClientDisconnect : TServerOnEvent read fOnDisconnect write fOnDisconnect;
  protected
    Procedure Execute; override;
    Procedure DoTerminate; override;
  end;

implementation

{ TDTSServer }

procedure TDTSServer.Broadcast(Data: TCommandHandling);
var
  i : integer;
  RecClient : TClientData;
  RecThread : TIdPeerThread;
begin
  try
    for i := 0 to fClientList.Count-1 do // iterate through client-list
    begin
      RecClient := TClientData(fClientList.Items[i]);          // get client-object
      RecThread := RecClient.Thread;    // get client-thread out of it
      RecThread.Connection.WriteLn(Data.SendFrames); // send the stuff
    end;
  finally
    FreeAndNil(Data);
  end;
end;

constructor TDTSServer.Create(Port: integer; BindIP : String = '127.0.0.1');
begin
  inherited Create(false);
  fPort := Port;
  fBindIP := BindIP;
end;

destructor TDTSServer.Destroy;
begin
  self.Terminate;
  self.WaitFor;

  inherited;
end;

procedure TDTSServer.DoTerminate;
begin
  inherited;

end;

procedure TDTSServer.Execute;
var
  MSG : TMsg;
  Binding : TIdSocketHandle;
begin
  inherited;

  fClientList := TObjectList.Create;

  fServer := TIdTCPServer.Create(nil);
//  fServer.TerminateWaitTime := 3000;
  fServer.Bindings.Clear;
  Binding := fServer.Bindings.Add;
  Binding.IP := fBindIP;
  Binding.Port := fPort;

  fServer.OnExecute := OnExecute;
  fServer.OnConnect := OnConnect;
  fServer.OnDisconnect := OnDisconnect;

  fServer.Active := true;

  while not Terminated do begin
    sleep(100);
  end;
//  while (GetMessage(msg, 0, 0, 0) and not Terminated) do
//    DispatchMessage(msg);

  fServer.Active := false;
  FreeAndNil(fServer);
  FreeAndNil(fClientList);
end;

procedure TDTSServer.OnConnect(AThread: TIdPeerThread);
var
  Data : TClientData;
begin
  Data := TClientData.Create;
  Data.DNS        := AThread.Connection.LocalName;
  Data.Connected  := Now;
  Data.LastAction := Now;
  Data.Thread     := AThread;

  AThread.Data := TClientData(Data);

  fClientList.Add(Data);
end;

procedure TDTSServer.OnDisconnect(AThread: TIdPeerThread);
var
  Data : TClientData;
begin
  if(Assigned(fOnDisconnect)) then
    fOnDisconnect(AThread);

  Data := TClientData(AThread.Data);
  fClientList.Remove(Data);
  AThread.Data := nil;
end;

procedure TDTSServer.OnExecute(AThread: TIdPeerThread);
var
  msg : string;
  cmd : TCommandHandling;
begin
  AThread.Connection.ReadTimeout := 1000;
  try
    msg := AThread.Connection.ReadLn;
  except
    exit;
  end;

  cmd := TCommandHandling.Create(CMDPong);
  try
    cmd.SetFrames(msg);
    if cmd.GetCmd = CMDPing then
    begin
      cmd.SetCommand(CMDPong);
      AThread.Connection.WriteLn(cmd.SendFrames);
    end else begin
      if Assigned(fOnRead) then
        //Weiter an die eigentliche Command behandlung.
        fOnRead(AThread, cmd);
      end;
  finally
    FreeAndNil(cmd);
  end;
end;

end.
Mfg

DataCool 22. Jun 2010 11:46

AW: TIdTCPServer / TIdTCPClient => Ping - Pong
 
Hi Jackie,

schonmal kurz vorab :
Der Server darf/sollte nicht innerhalb eines TTHreads laufen, das war vielleicht bei Deinen Sockets erforderlich,
aber bei Indy ist das so nicht gewollt, weil Indy intern selber alles in Threads handelt.
Also leite Deine Klasse "TDTSServer" NICHT von TThread ab, sondern lass das ganze mal als einfache Klasse laufen.
OnExecute und OnTerminate ersetzt Du dann mit Sart und Stop oder wie auch immer Du es brauchst.

Greetz Data


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:37 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz