Search code examples
delphiindy

How to send text from Indy TCPServer to TCPClient


I need a simple fix in my chat app made with TIdTCPServer and TIdTCPClient. Please, with no additional code, just to send and receive text.

procedure TServerApp1.Button1Click(Sender: TObject);
var
  AContext : TIdContext;
begin
  AContext.Connection.Socket.Write(length(newMSG.Text));
  AContext.Connection.Socket.Write(newMSG.Text);
end;

Solution

  • TIdTCPServer has a Contexts property containing a list of connected clients. You would have to lock and iterate through that list looking for the client to send to. For example:

    procedure TServerApp1.Button1Click(Sender: TObject);
    var
      Buf: TIdBytes;
      List: TIdContextList;
      Context: TIdContext;
      I: Integer;
    begin
      // this step is important, as Length(newMSG.Text) will not
      // be the actual byte count sent by Write(newMSG.Text)
      // if the text contains any non-ASCII characters in it!
      Buf := ToBytes(newMSG.Text, IndyTextEncoding_UTF8);
    
      List := IdTCPServer1.Contexts.LockList;
      try
        for I := 0 to List.Count-1 do
        begin
          Context := TIdContext(List[I]);
          if (Context is the one you are interested in) then
          begin
            Context.Connection.IOHandler.Write(Length(Buf));
            Context.Connection.IOHandler.Write(Buf);
            Break;
          end;
        end;
      finally
        IdTCPServer1.Contexts.UnlockList
      end;
    end;
    

    However, I do not recommend sending messages directly to a client like this. That can cause race conditions that may corrupt your communications. A safer option is to give each client its own thread-safe queue that you can push messages into when needed, and then you can have the TIdTCPServer.OnExecute event handler send the queued messages when it is safe to do so. See my answer to the following question for an example:

    ¿How can I send and recieve strings from tidtcpclient and tidtcpserver and to create a chat?