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
Benutzerbild von DataCool
DataCool

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

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 22. Jun 2010, 11: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
 
#2

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

  Alt 22. Jun 2010, 11: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
 
#3

AW: TIdTCPServer / TIdTCPClient => Ping - Pong

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


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 23:02 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