AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Netzwerke Delphi TIdTCPServer / TIdTCPClient => Ping - Pong
Thema durchsuchen
Ansicht
Themen-Optionen

TIdTCPServer / TIdTCPClient => Ping - Pong

Ein Thema von Jackie1983 · begonnen am 21. Jun 2010 · letzter Beitrag vom 22. Jun 2010
Antwort Antwort
Seite 2 von 2     12   
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#11

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 21. Jun 2010, 16:49
Hi,

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

Greetz Data
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Jackie1983

Registriert seit: 12. Mär 2007
486 Beiträge
 
#12

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 21. Jun 2010, 16:56
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

Geändert von Jackie1983 (21. Jun 2010 um 17:17 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#13

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 21. Jun 2010, 17:29
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
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Jackie1983

Registriert seit: 12. Mär 2007
486 Beiträge
 
#14

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 21. Jun 2010, 17:35
hi,

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

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;
  Mit Zitat antworten Zitat
Jackie1983

Registriert seit: 12. Mär 2007
486 Beiträge
 
#15

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 21. Jun 2010, 19:07
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

Geändert von Jackie1983 (21. Jun 2010 um 20:04 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#16

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 22. Jun 2010, 12:14
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

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
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Jackie1983

Registriert seit: 12. Mär 2007
486 Beiträge
 
#17

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 22. Jun 2010, 12:30
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
  Mit Zitat antworten Zitat
Benutzerbild von DataCool
DataCool

Registriert seit: 10. Feb 2003
Ort: Lingen
909 Beiträge
 
Delphi 10.3 Rio
 
#18

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 22. Jun 2010, 12:46
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
Der Horizont vieler Menschen ist ein Kreis mit Radius Null, und das nennen sie ihren Standpunkt.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 2     12   


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:09 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