Recent

Author Topic: How to get message from Server to Client. tIdTCPServer to TIdTCPClient [SOLVED]  (Read 2300 times)

Nolan

  • New Member
  • *
  • Posts: 15
i want to get back some value sent from the Client to the server and I want the server to send something like a Response string.
Now the Client sends a command to the server to execute a function (This works good) now, in the same vein, i want a scenario where it returns something like 'Done' once the server has executed the program and it should show on the Label on the Client that everything is fine.

I have two source codes for the Client and the server Which is given thus :

Client

Code: Pascal  [Select][+][-]
  1. unit Client;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent,
  8.   IdComponent, IdTCPConnection, IdTCPClient;
  9.  
  10. type
  11.   TForm3 = class(TForm)
  12.     IdTCPClient1: TIdTCPClient;
  13.     Button1: TButton;
  14.     Label1: TLabel;
  15.     procedure FormCreate(Sender: TObject);
  16.     procedure Button1Click(Sender: TObject);
  17.   private
  18.     { Private declarations }
  19.   public
  20.     { Public declarations }
  21.   end;
  22.  
  23. var
  24.   Form3: TForm3;
  25.  
  26. implementation
  27.  
  28. {$R *.dfm}
  29.  
  30. procedure TForm3.Button1Click(Sender: TObject);
  31. begin
  32.   IdTCPClient1.Socket.WriteLn('SayHello');
  33. end;
  34.  
  35. procedure TForm3.FormCreate(Sender: TObject);
  36. begin
  37.       IdTCPClient1:= TIdTCPClient.create(nil);
  38.       IdTCPClient1.Host := 'localhost';
  39.       IdTCPClient1.Port := 45000;
  40.       IdTCPClient1.Connect;
  41. end;
  42.  
  43. end.
  44.  

So this is for the server

Server

Code: Pascal  [Select][+][-]
  1. unit Server;
  2.  
  3. interface
  4.  
  5. uses
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdBaseComponent, IdComponent,
  8.   IdCustomTCPServer, IdTCPServer, IdContext;
  9.  
  10. type
  11.   TForm4 = class(TForm)
  12.     IdTCPServer1: TIdTCPServer;
  13.     procedure FormCreate(Sender: TObject);
  14.     procedure IdTCPServer1Execute(AContext: TIdContext);
  15.   private
  16.     { Private declarations }
  17.   public
  18.     { Public declarations }
  19.   end;
  20.  
  21. var
  22.   Form4: TForm4;
  23.  
  24. implementation
  25.  
  26. {$R *.dfm}
  27.  
  28. procedure SayHelloWorldMessageBox();
  29. begin
  30.   ShowMessage('Hello World!');
  31. end;
  32.  
  33. procedure TForm4.FormCreate(Sender: TObject);
  34. begin
  35.       IdTCPServer1 := TIdTCPServer.Create(nil);
  36.       IdTCPServer1.DefaultPort := 45000;
  37.       IdTCPServer1.OnExecute:= IdTCPServer1Execute;
  38.       IdTCPServer1.Active:=true;
  39. end;
  40.  
  41. procedure TForm4.IdTCPServer1Execute(AContext: TIdContext);
  42.     var
  43.     recv:string;
  44.  
  45. begin
  46.         recv := AContext.Connection.Socket.ReadLn;
  47.     if recv = 'SayHello' then
  48.     begin
  49.           SayHelloWorldMessageBox();
  50.           AContext.Connection.IOHandler.Write('Done');
  51.     end;
  52.  
  53. end;
  54.  
  55. end.


Why does it not send a message from the Server to the Client to Display that "done", or basically, How do I display it to show everything is working good? New to this , i need Help here.
« Last Edit: August 11, 2022, 12:39:21 pm by Nolan »

paweld

  • Hero Member
  • *****
  • Posts: 966
Best regards / Pozdrawiam
paweld

Nolan

  • New Member
  • *
  • Posts: 15
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #2 on: August 06, 2022, 06:59:26 pm »
https://forum.lazarus.freepascal.org/index.php/topic,60194.msg449534.html#msg449534

I do not see anything like that there. I have been able to send commands from the Client to the server, now i want the server to send back some response to the Client.
Cannot get it to work.

paweld

  • Hero Member
  • *****
  • Posts: 966
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #3 on: August 06, 2022, 07:21:48 pm »
Type in a edit control "hello" or "2+2" and click "send" button.

In general, you need to start a thread after the client connection, which will read responses from the server.
Best regards / Pozdrawiam
paweld

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #4 on: August 06, 2022, 11:30:22 pm »
Why are you asking in this forum when you're using Delphi? There's almost certainly more appropriate places... as you should have realised by now, since you've been doing the same thing for months.

Try recompiling with FPC/Lazarus and more of us might be interested... :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Nolan

  • New Member
  • *
  • Posts: 15
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #5 on: August 06, 2022, 11:43:02 pm »
Why are you asking in this forum when you're using Delphi? There's almost certainly more appropriate places... as you should have realised by now, since you've been doing the same thing for months.

Try recompiling with FPC/Lazarus and more of us might be interested... :-)

MarkMLl

Ahh, I see, Let me download Lazarus then. Thanks for the heads up.

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #6 on: August 07, 2022, 10:18:17 am »
Ahh, I see, Let me download Lazarus then. Thanks for the heads up.

Well taken :-) It was your usage of "vcl." that I spotted, you might find minor differences in Lazarus/LCL's handling of things but all in all a high priority is Delphi compatibility... as far as is possible within the constraint of portability to a wide range of target OSes etc.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1311
    • Lebeau Software
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #7 on: August 08, 2022, 09:06:30 pm »
Why are you asking in this forum when you're using Delphi? There's almost certainly more appropriate places... as you should have realised by now, since you've been doing the same thing for months.

Official Indy forum: https://atozed.com/forums/forum-9.html

Also see: https://www.indyproject.org/support/
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Remy Lebeau

  • Hero Member
  • *****
  • Posts: 1311
    • Lebeau Software
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #8 on: August 08, 2022, 09:15:24 pm »
Now the Client sends a command to the server to execute a function (This works good) now, in the same vein, i want a scenario where it returns something like 'Done' once the server has executed the program and it should show on the Label on the Client that everything is fine.

The simplest solution is to just call ReadLn() after WriteLn(), eg:

Code: Pascal  [Select][+][-]
  1. procedure TForm3.Button1Click(Sender: TObject);
  2. begin
  3.   IdTCPClient1.Socket.WriteLn('SayHello');
  4.   Label1.Caption := IdTCPClient1.Socket.ReadLn;
  5. end;

Code: Pascal  [Select][+][-]
  1. procedure SayHelloWorldMessageBox();
  2. begin
  3.   ShowMessage('Hello World!');
  4. end;

Note that TIdTCPServer is multi-threaded, where the OnExecute event is fired in worker threads, but ShowMessage() is not a thread-safe function. It should never be called outside of the main UI thread.  So, either use TThread.Synchronize() or equivalent to call ShowMessage() in the main UI thread, or else use a thread-safe function, such as Windows.MessageBox().

Code: Pascal  [Select][+][-]
  1. AContext.Connection.IOHandler.Write('Done');

You should call Socket.WriteLn() instead of Socket.Write(), otherwise the client won't know when the string ends, unless you close the connection (which you are not doing) after sending the string.

Why does it not send a message from the Server to the Client to Display that "done",

It does (assuming ShowMessage() does not deadlock/crash the calling thread), but the client you have shown is not coded to read the message.
Remy Lebeau
Lebeau Software - Owner, Developer
Internet Direct (Indy) - Admin, Developer (Support forum)

Nolan

  • New Member
  • *
  • Posts: 15
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #9 on: August 10, 2022, 05:54:00 pm »
Now the Client sends a command to the server to execute a function (This works good) now, in the same vein, i want a scenario where it returns something like 'Done' once the server has executed the program and it should show on the Label on the Client that everything is fine.

The simplest solution is to just call ReadLn() after WriteLn(), eg:

Code: Pascal  [Select][+][-]
  1. procedure TForm3.Button1Click(Sender: TObject);
  2. begin
  3.   IdTCPClient1.Socket.WriteLn('SayHello');
  4.   Label1.Caption := IdTCPClient1.Socket.ReadLn;
  5. end;

Code: Pascal  [Select][+][-]
  1. procedure SayHelloWorldMessageBox();
  2. begin
  3.   ShowMessage('Hello World!');
  4. end;

Note that TIdTCPServer is multi-threaded, where the OnExecute event is fired in worker threads, but ShowMessage() is not a thread-safe function. It should never be called outside of the main UI thread.  So, either use TThread.Synchronize() or equivalent to call ShowMessage() in the main UI thread, or else use a thread-safe function, such as Windows.MessageBox().

Code: Pascal  [Select][+][-]
  1. AContext.Connection.IOHandler.Write('Done');

You should call Socket.WriteLn() instead of Socket.Write(), otherwise the client won't know when the string ends, unless you close the connection (which you are not doing) after sending the string.

Why does it not send a message from the Server to the Client to Display that "done",

It does (assuming ShowMessage() does not deadlock/crash the calling thread), but the client you have shown is not coded to read the message.

You are a Blessing, Thank You so much! Tried all you did and it responded fine! Now i can do a two way app.
Thank you. Will try to see how to code a VNC now!

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #10 on: August 10, 2022, 06:24:36 pm »
Thank you. Will try to see how to code a VNC now!

Hopefully using FPC/Lazarus :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Nolan

  • New Member
  • *
  • Posts: 15
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #11 on: August 10, 2022, 09:49:01 pm »
Thank you. Will try to see how to code a VNC now!

Hopefully using FPC/Lazarus :-)

MarkMLl

Yes. Its installed on my PC. I have started learning with it already. Thanks guys for the heads up

MarkMLl

  • Hero Member
  • *****
  • Posts: 6646
Re: How to get message from Server to Client. tIdTCPServer to TIdTCPClient
« Reply #12 on: August 10, 2022, 10:00:28 pm »
Yes. Its installed on my PC. I have started learning with it already. Thanks guys for the heads up

Our pleasure, and welcome to the community :-)

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

 

TinyPortal © 2005-2018