This time I will show you how to make a multithreaded Client/Server-application with Indy. The server will simulate a state change: "working / idle" every 10 secs. The client polls the server at a given interval, and presents the server-state. Possible exceptions are trapped. Try connecting with multiple clients.
Indy components are open-source and can be downloaded freely from: www.nevrona.com/indy.
If you wan't the project-files, they're here:
{-----------------------------------------------------------------------------
Unit Name: sUnit1
Author: Mats Asplund
Purpose: IndyServer
-----------------------------------------------------------------------------}
unit sUnit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPServer, IdException, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Label1: TLabel;
Timer1: TTimer;
IdTCPServer1: TIdTCPServer;
Label2: TLabel;
procedure Timer1Timer(Sender: TObject);
procedure IdTCPServer1Connect(AThread: TIdPeerThread);
procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);
procedure FormCreate(Sender: TObject);
private
Working, Disconnected: Boolean;
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
IdTCPServer1.DefaultPort:= 12345;
IdTCPServer1.Active:= true;
Timer1.Interval:= 10000;
Timer1.Enabled:= true;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Working:= not Working;
end;
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
Disconnected:= false;
with IdTCPServer1 do
begin
try
while not Disconnected do
begin
if Working then
begin
AThread.Connection.Writeln('Working');
Label2.Caption:= 'Sent: "Working"';
end
else
begin
AThread.Connection.Writeln('Idle');
Label2.Caption:= 'Sent: "Idle"';
end;
Sleep(500);
Label2.Caption:= '';
Sleep(500);
end;
except
// on EIdSocketError do
// ShowMessage('Client disconnected !');
end;
end
end;
procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
begin
Disconnected:= true;
end;
end.
{-----------------------------------------------------------------------------
Unit Name: cUnit1
Author: Mats Asplund
Purpose: IndyClient
-----------------------------------------------------------------------------}
unit cUnit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient,
StdCtrls, ExtCtrls, Buttons, passoverbtn, IdException;
type
TForm1 = class(TForm)
IdTCPClient1: TIdTCPClient;
Memo1: TMemo;
Label1: TLabel;
Timer1: TTimer;
Edit1: TEdit;
Label2: TLabel;
Edit2: TEdit;
Label3: TLabel;
Button1: TButton;
Button2: TButton;
procedure Timer1Timer(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
public
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
Timer1.Interval:= 100;
Timer1.Enabled:= false;
IdTCPClient1.Host:= '127.0.0.1';
IdTCPClient1.Port:= 12345;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
try
Memo1.Lines.Add(IdTCPClient1.ReadLn);
except
on EIdConnClosedGracefully do
begin
Timer1.Enabled:= false;
ShowMessage('The server closed the connection !' + #13#10 +
'Try connecting again.');
end;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
try
IdTCPClient1.Host:= Edit1.Text;
IdTCPClient1.Connect;
ShowMessage('Connected to ' + Edit1.Text);
Timer1.Interval:= StrToInt(Edit2.Text);
Timer1.Enabled:= true;
except
on EIdConnClosedGracefully do
ShowMessage('The server closed the connection !');
on EIdAlreadyConnected do
ShowMessage('Your''e already connected !');
on EIdSocketError do
ShowMessage('Can''t connect to server !');
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Timer1.Enabled:= false;
IdTCPClient1.Disconnect;
ShowMessage('Disconnected from ' + Edit1.Text);
end;
end.