Atozed Forums
searching for open available ports for listening on server side TCP/UDP - Printable Version

+- Atozed Forums (https://www.atozed.com/forums)
+-- Forum: Indy (https://www.atozed.com/forums/forum-8.html)
+--- Forum: Indy General Discussion (https://www.atozed.com/forums/forum-9.html)
+--- Thread: searching for open available ports for listening on server side TCP/UDP (/thread-4333.html)



searching for open available ports for listening on server side TCP/UDP - Ahmed Sayed - 07-18-2024

Hi,
I am looking for a clean way to make a service search for available ports to open it and listen on that port and then set the chosen port number in the Windows registry for clients to use to connect to it, whether it is using TCP or UDP. Is there a function out of the box for Indy to use, or do I need to do this the hard way and loop through random numbers starting from specific numbers and keep going up until I find an open port? 

Currently, What I am doing is that I get the process ID and then adding 8000 to it and use that as the port number for the service, but I want a cleaner way to do so.


RE: searching for open available ports for listening on server side TCP/UDP - rlebeau - 07-18-2024

(07-18-2024, 11:21 AM)Ahmed Sayed Wrote: Is there a function out of the box for Indy to use, or do I need to do this the hard way and loop through random numbers starting from specific numbers and keep going up until I find an open port? 

You don't need to search manually at all. Simply bind the listening socket to port 0, and then the OS will pick an available ephemeral port for you. After the binding is finished, you can query the socket to know which port was chosen.

For example in Indy:

Code:
IdTCPServer.Bindings.Clear;
IdTCPServer.DefaultPort := 0;
// optional: populate IdTCPServer.Bindings for specific network adapters
// as needed, but set IdTCPServer.Bindings[Index].Port = 0...
IdTCPServer.Active := True;
for I := 0 to IdTCPServer.Bindings.Count-1 do begin
  WriteLn('Listening on ' + IdTCPServer.Bindings[I].IP + ':' + IntToStr(IdTCPServer.Bindings[I].Port));
end;

The same applies to UDP servers, too.

(07-18-2024, 11:21 AM)Ahmed Sayed Wrote: Currently, What I am doing is that I get the process ID and then adding 8000 to it and use that as the port number for the service, but I want a cleaner way to do so.

Obviously, that won't work for PID 57536 and higher. Also, just picking random ports is likely to run into conflicts at times. That is why the OS reserves a pool of ephemeral ports for apps to use.


RE: searching for open available ports for listening on server side TCP/UDP - Ahmed Sayed - 07-19-2024

Thanks, but I see that it binds to 2 sockets one for ipv4 and the other for ipv6, but is there a way where I can make it bind only to ipv4 I don't need v6.

Also, is there a limit on the number of ephemeral ports generated by the OS as you said?


RE: searching for open available ports for listening on server side TCP/UDP - rlebeau - 07-19-2024

(07-19-2024, 07:53 AM)Ahmed Sayed Wrote: I see that it binds to 2 sockets one for ipv4 and the other for ipv6

Yes, but only when the Bindings collection is empty when activating the server, and only if the OS supports binding both IPv4 and IPv6 at the same time.

(07-19-2024, 07:53 AM)Ahmed Sayed Wrote: is there a way where I can make it bind only to ipv4 I don't need v6.

Yes - simply add an IPv4 item to the Bindings collection before activating the server (that is the "optional" comment in my previous example), eg:

Code:
IdTCPServer.Bindings.Clear;
// '' means the same as '0.0.0.0.0' to bind to all local adapters.
// You can also use a specific adapter's IP instead...
IdTCPServer.Bindings.Add.SetBinding('', 0, Id_IPv4);
IdTCPServer.Active := True;
for I := 0 to IdTCPServer.Bindings.Count-1 do begin
  WriteLn('Listening on ' + IdTCPServer.Bindings[I].IP + ':' + IntToStr(IdTCPServer.Bindings[I].Port));
end;

(07-19-2024, 07:53 AM)Ahmed Sayed Wrote: Also, is there a limit on the number of ephemeral ports generated by the OS as you said?

Yes, of course there is a limit, as ports are a finite resource. The actual range of ports available differs from one OS to another, and even OS configurations.