I'm still getting used to Indy, being a multi-threaded socket system with vast capabilities. One of the big things I've seen is how a server socket can have a number of different bindings. For example, you could have 3 bindings for 3 ports on the same IP address. I'm using Indy 10 on Delphi XE2.
I'm re-building an old system of mine which uses the old fashioned TServerSocket
and TClientSocket
components from ScktComps
and re-doing it with Indy TIdTCPServer
and TIdTCPClient
. The old system actually consists of 3 completely different server/client sockets on each end, each socket serving a distinct purpose, and working together - similar to how FTP uses one socket for binary data and the other socket for commands.
Is it possible to mimic three separate server/client sockets within the same component using these bindings? It would be great if I can declare just one server socket with 3 ports bound, and same on the client, connected to 3 different ports on the server. All I would like to do is eliminate the need to create 3 separate server/client socket components and combine them into one.
Yes, you can use a single TIdTCPServer
to manage multiple ports at a time. On the client side, you still need 3 distinct client components to connect to the different ports, though.
Create 3 entries in the TIdTCPServer.Bindings
collection, one for each local IP/Port that you want to listen on, where the TIdSocketHandle.Port
property would be the equivilent of the TServerSocket.Port
property. TServerSocket
does not natively support binding to a specific IP (though it can be done with some manual work), but the TIdSocketHandle.IP
property is used for that purpose, where a blank string is equivilent to INADDR_ANY
.
In the TIdCPServer.OnConnect
, TIdCPServer.OnDisconnect
, and TIdCPServer.OnExecute
events, you can use the TIdContext.Binding.IP
and TIdContext.Binding.Port
properties to differentiate which binding the calling socket is connected to.
A common use of this is to support SSL and non-SSL clients on different ports, such as for protocols like POP3 and SMTP which support implicit and explicit SSL/TLS on different ports. TIdHTTPServer
does this for supporting HTTP
and HTTPS
urls on a single server (you can use the TIdHTTPServer.OnQuerySSLPort
to customize which ports use SSL/TLS versus not).
For example:
procedure TForm1.StartButtonCick(Sender: TObject);
begin
IdTCPServer1.Active := False;
IdTCPServer1.Bindings.Clear;
with IdTCPServer1.Bindings.Add do
begin
IP := ...;
Port := 2000;
end;
with IdTCPServer1.Bindings.Add do
begin
IP := ...;
Port := 2001;
end;
with IdTCPServer1.Bindings.Add do
begin
IP := ...;
Port := 2002;
end;
IdTCPServer1.Active := True;
end;
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
case AContext.Binding.Port of
2000: begin
// do something...
end;
2001: begin
// do something else...
end;
2002: begin
// do yet something else ...
end;
end;
end;