title: Indy TIdTCPServer TIdTCPClient data exchange
body: <p>I spent some time to write a simple application to exchange data between <code>TIdTCPServer</code> and <code>TIdTCPClient</code>. But now I'm stuck.<br>
  I can send data from <code>TIdTCPClient</code> to <code>TIdTCPServer</code> and can process this.<br>
  But have no idea and official documentation didn't give any clue how to send data from <code>TIdTCPServer</code> and process it on <code>TIdTCPClient</code>. Please advise.</p>
  
  <p>My code is simple:</p>
  
  <p>main application:</p>
  
  <pre><code>var
    Form1: TForm1;
  
  implementation
  
  uses ClientThread, ServerThread;
  
  var
    ClientThread: TClientThread;
    ServerThread: TServerThread;
  
  {$R *.fmx}
  
  procedure TForm1.Button1Click(Sender: TObject);
  var OutputDebugString:string;
  begin
    ServerThread:=TServerThread.Create(False);
    ServerThread.Priority:=tpNormal;
  end;
  
  procedure TForm1.Button2Click(Sender: TObject);
  begin
    ClientThread:=TClientThread.Create(False);
    ClientThread.Priority:=tpNormal;
   end;
  </code></pre>
  
  <p>Server Thread:</p>
  
  <pre><code>unit ServerThread;
  
  interface
  
  uses
    Classes, System.SysUtils, IdContext, IdTCPServer, TaskQue;
  
  type
    TServerThread = class(TThread) //MyThread - заданное нами имя потока.
    private
      { Private declarations }
    protected
      procedure Execute; override;
    end;
  
   TServer = class(TObject)
     IdTCPServer1: TIdTCPServer;
     procedure IdTCPServer1Execute(AContext: TIdContext);
     procedure IdTCPServer1Connect(AContext: TIdContext);
    private
     { Private declarations }
     constructor Create;
    public
    end;
  
  type
  TDatagram = record
      Proto: byte;
      Command: word;
      DataSize: word;
      data: array [0..4096] of byte;
    end;
  
  var
    Server : TServer;
  
  implementation
  
  uses YouFreedom;
  
  constructor TServer.Create;
  begin
   inherited Create;
   IdTCPServer1 := TIdTCPServer.Create(nil);
   IdTCPServer1.Bindings.Clear;
  // IdTCPServer1.DefaultPort := 10001;
    try
      with idTCPserver1.Bindings.Add do
      begin
        IP := '127.0.0.1';
        Port := 10001;
      end;
    finally     //dirty hack
        idTCPserver1.Bindings.Add.IP := '127.0.0.1';
        idTCPserver1.Bindings.Add.Port := 10002;
    end;
  // idTCPserver1.Bindings.Add.Port:=10001;
  // IdTCPServer1.Bindings.Add.IP := '127.0.0.1';
   IdTCPServer1.Tag := 0;
   IdTCPServer1.TerminateWaitTime := 5000;
   IdTCPServer1.OnConnect := IdTCPServer1Connect;
   IdTCPServer1.OnExecute := IdTCPServer1Execute;
  end;
  
  procedure TServer.IdTCPServer1Execute(AContext: TIdContext);
  
  var
    MIRec: TDatagram;
    msRecInfo: TMemoryStream;
    size: integer;
    i:integer;
    recieve:byte;
    respstream: TMemoryStream;
  begin
    try
     msRecInfo:= TMemoryStream.Create;
     AContext.Connection.IOHandler.ReadStream(msRecInfo, -1, false);
     msRecInfo.Position := 0;
     msRecInfo.ReadBuffer(MIRec, msRecInfo.size);
     Form1.addtoque := '1';
  //   Form1.s := inttostr(MIRec.Proto)
    Form1.Memo1.Lines.Add('Proto = ' + inttostr(MIRec.Proto));
    finally
     msRecInfo.Free
    end;
  end;
  
  procedure TServer.IdTCPServer1Connect(AContext: TIdContext);
  begin
  //AContext.Connection.Socket.WriteLn('hello');
  end;
  
  procedure TServerThread.Execute;
  begin
   Server := TServer.Create;
   try
    Server.IdTCPServer1.Active := True;
   except
        on E: Exception do
         // OutputDebugString(PChar(E.ToString)); //do something
        end;
  end;
  
  
  end.
  </code></pre>
  
  <p>Client thread:</p>
  
  <pre><code>unit ClientThread;
  
  interface
  
  uses
    Classes, IdTCPClient;
  
  type
    TClientThread = class(TThread) //MyThread - заданное нами имя потока.
    private
      { Private declarations }
    protected
      procedure Execute; override;
    end;
  
   TClient = class(TObject)
     IdTCPClient1: TIdTCPClient;
  //   procedure IdTCPClient1OnWorkBegin(AContext: TIdContext);
    private
     { Private declarations }
     constructor Create;
    public
    end;
  
  implementation
  
  type
  TDatagram = record
      Proto: byte;
      Command: word;
      DataSize: word;
      data: array [0..4096] of byte;
    end;
  
  var
    ClientConnection : TClient;
  
  constructor TClient.Create;
  begin
   inherited Create;
   IdTCPClient1 := TIdTCPClient.Create(nil);
  // IdTCPClient1.ReuseSocket := rsOSDependent;
   IdTCPClient1.Host := '127.0.0.1';
   IdTCPClient1.Port := 10001;
  // IdTCPClient1.OnWorkBegin := IdTCPClient1OnWorkBegin;
  end;
  
  procedure TClientThread.Execute;
  var
    MIRec: TDatagram;
    msRecInfo: TMemoryStream;
    i,k:integer;
    Client1: TIdTCPClient;
    recieve:byte;
    respstream: TMemoryStream;
  begin
    ClientConnection := TClient.Create;
    ClientConnection.IdTCPClient1.Connect;
    for k := 1 to 5 do begin
  
    if ClientConnection.IdTCPClient1.Connected then begin
  {   MIRec.DataSize := 64;
     for i:=0 to MIRec.DataSize do
      MIRec.data[i] := i;
     for i:=129 to 4096 do MIRec.data[i] := 0;}
     MIRec.Proto := 1;
     MIRec.Command :=1;
    try
      msRecInfo := TMemoryStream.Create;
      msRecInfo.WriteBuffer(MIRec, SizeOf(MIRec));
      msRecInfo.Position := 0;
      ClientConnection.IdTCPClient1.IOHandler.Write(msRecInfo, msRecInfo.Size, true);
    finally
      msRecInfo.Free;
    end;
    end;
    end
   end;
  
  
  
  
  end.
  </code></pre>