Einzelnen Beitrag anzeigen

mjustin

Registriert seit: 14. Apr 2008
3.006 Beiträge
 
Delphi 2009 Professional
 
#34

AW: .exe zu .exe Kommunikation

  Alt 14. Sep 2018, 14:03
Hier ist ein Beispiel, in dem ein Indy TCP Server einem Client eine einfache Nachricht sendet. (Artikel Link)

Der Server-Code muss nur in der DoExecute-Methode angepasst werden und dort z.B. das nächste an den Client zu sendende Datenpaket erstellen. Da die Server-Klasse für jede Connection einen eigenen Thread verwendet, gilt der Code in der DoExecute Methode für die aktuelle Connection. DoExecute wird in einer Schleife ausgeführt bis die Verbindung getrennt wurde oder eine Exception auftritt.

Der Client-Code läuft in einem Thread um im Hintergrund auf neue Nachrichten des Servers zu warten. Der ReadLn Aufruf wartet, bis entweder eine Nachricht eintrifft, oder das Timeout erreicht ist, und wird dann wieder ausgeführt.

Delphi-Quellcode:
unit Unit1;
 
interface
 
uses
  IdCustomTCPServer, IdTCPClient, IdContext,
  SysUtils, Classes, Forms, StdCtrls, Controls;
 
type
  TMyPushClientThread = class(TThread)
  private
    TCPClient: TIdTCPClient;
    FLog: TStrings;
  public
    constructor Create(AHost: string; APort: Word; ALog: TStrings);
    destructor Destroy; override;
    procedure Execute; override;
  end;
 
  TMyPushServer = class (TIdCustomTCPServer)
  protected
    function DoExecute(AContext: TIdContext): Boolean; override;
  end;
 
  TServerPushExampleForm = class(TForm)
    MemoLog: TMemo;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    ExampleClient: TMyPushClientThread;
    ExampleServer: TMyPushServer;
  end;
 
var
  ServerPushExampleForm: TServerPushExampleForm;
 
implementation
 
uses
  IdGlobal;
 
{$R *.dfm}
 
procedure TServerPushExampleForm.FormCreate(Sender: TObject);
begin
  ExampleServer := TMyPushServer.Create;
  ExampleServer.DefaultPort := 8088;
  ExampleServer.Active := True;
 
  ExampleClient := TMyPushClientThread.Create('localhost', 8088, MemoLog.Lines);
end;
 
procedure TServerPushExampleForm.FormDestroy(Sender: TObject);
begin
  ExampleServer.Free;
  ExampleClient.Terminate;
  ExampleClient.WaitFor;
  ExampleClient.Free;
end;
 
{ TMyPushServer }
 
function TMyPushServer.DoExecute(AContext: TIdContext): Boolean;
begin
  Result := inherited;
 
  // simulate hard work
  Sleep(Random(3000));
 
  AContext.Connection.IOHandler.WriteLn(
    'Completed at ' + TimeToStr(Now), IndyTextEncoding_UTF8);
end;
 
{ TMyPushClientThread }
 
constructor TMyPushClientThread.Create(AHost: string; APort: Word; ALog: TStrings);
begin
  inherited Create(False);
 
  FLog := ALog;
 
  TCPClient := TIdTCPClient.Create;
  TCPClient.Host := AHost;
  TCPClient.Port := APort;
  TCPClient.ReadTimeout := 500;
end;
 
destructor TMyPushClientThread.Destroy;
begin
  TCPClient.Free;
  inherited;
end;
 
procedure TMyPushClientThread.Execute;
var
  S: string;
begin
  TCPClient.Connect;
 
  while not Terminated do
  begin
    S := TCPClient.IOHandler.ReadLn(IndyTextEncoding_UTF8);
 
    if not TCPClient.IOHandler.ReadLnTimedout then
    begin
      TThread.Queue(nil,
        procedure
        begin
          FLog.Append(S);
        end);
    end;
 
  end;
 
  TCPClient.Disconnect;
end;
 
end.
Michael Justin
  Mit Zitat antworten Zitat