I installed the Indy package, I got tons of new tabs and tons of new components under every new tab.
To be honest it is not really helpful.
I want to make a server-client communication like in this Delphi article: https://www.thoughtco.com/write-network-aware-applications-with-delphi-4071210
You can use Indy's
TIdTCPClient and
TIdTCPServer component for that. You just have to take into account that Indy uses blocking sockets exclusively, whereas Delphi's
TClientSocket/
TServerSocket use non-blocking sockets by default (but can also use blocking sockets). It is best not to perform blocking operations in the main UI thread (Indy servers are multi-threaded), so
typically you should perform your client actions in a separate worker thread so as not to cause blockages in the UI (but, for purposes of this example, I'll skip that. You can put a
TIdAntiFreeze component on your main Form instead).
I don't know sockets, but this example is pretty good and easy to start with. Unfortunately it is under Delphi. This is why I need something very similar.
A direct translation of that article's example would look like the following in Indy:
Server:
interface
uses
..., IdContext, IdTCPServer;
type
TForm1 = class(TForm)
IdTCPServer1: TIdTCPServer;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure IdTCPServer1Execute(AContext : TIdContext);
...
end;
...
implementation
uses
IdSync;
procedure TForm1.FormCreate(Sender: TObject);
begin
IdTCPServer1.DefaultPort := 23;
IdTCPServer1.Active := True;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
IdTCPServer1.Active := False;
end;
// TIdTCPServer is a multi-threaded component, so you MUST sync with
// the main thread when accessing UI controls. Indy provides two utility
// classes for this purpose - TIdSync (synchronous) and TIdNotify (asynchronous).
// Or, you can use whatever inter-thread sync mechanism you want, as
// long as it is thread-safe. Opt for asynchronous when possible, to avoid
// blocking the server if client data arrives during shutdown...
type
TAddToMemo = class(TIdNotify)
private
FPeerIP, FMsg: string;
protected
procedure DoNotify; override;
public
constructor Create(const APeerIP, AMsg: string); reintroduce;
end;
constructor TAddToMemo.Create(const APeerIP, AMsg: string);
begin
inherited Create;
FPeerIP := APeerIP;
FMsg := AMsg;
end;
procedure TAddToMemo.DoNotify;
begin
Form1.Memo1.Lines.Add(FPeerIP + ' sends :') ;
Form1.Memo1.Lines.Add(FMsg);
end;
procedure TForm1.IdTCPServer1Execute(AContext : TIdContext);
var
sRec: string;
begin
// check if there is any data pending
AContext.Connection.IOHandler.CheckForDataOnSource(100);
AContext.Connection.IOHandler.CheckForDisconnect;
if AContext.Connection.IOHandler.InputBufferIsEmpty then Exit;
// read all pending data as a single string
sRec := AContext.Connection.IOHandler.InputBufferAsString;
// add data to the UI
TAddToMemo.Create(AContext.Binding.PeerIP, sRec).Notify;
end;
Client:
interface
uses
..., IdTCPClient;
type
TForm1 = class(TForm1)
IdTCPClient1 := TIdTCPClient;
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button1Click(Sender: TObject);
...
end;
...
implementation
procedure TForm1.FormCreate(Sender: TObject);
begin
IdTCPClient1.Port := 23;
//local TCP/IP address of the server
IdTCPClient1.Host := '192.168.167.12';
IdTCPClient1.Connect;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
IdTCPClient1.Disconnect;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
if IdTCPClient1.Connected then
IdTCPClient1.IOHandler.Write(Edit1.Text);
end;
Though, a slightly more efficient example would look like this instead:
Server:
procedure TForm1.IdTCPServer1Execute(AContext : TIdContext);
var
sRec: string;
begin
sRec := AContext.Connection.IOHandler.ReadLn;
TAddToMemo.Create(AContext.Binding.PeerIP, sRec).Notify;
end;
Client:
procedure TForm1.Button1Click(Sender: TObject);
begin
if IdTCPClient1.Connected then
IdTCPClient1.IOHandler.WriteLn(Edit1.Text);
end;
Edit: it is really confusing. I removed the Indy package and installed the Synapse. But, cannot see any new components. Does not Synapse have any component?
No, it does not. It has utility classes that you have to instantiate in code when needed.