How to find a free TCP port
Asked Answered
C

4

13

How do I find a completely free TCP port on a server? I have tried the command line;

netstat -an

but I am told the ones with a status of LISTENING are already being used.

I also tried a tool called TCPView but again it only showed which TCP ports were being used. I know how to telnet to a port to check its open but I need to find one that is free.

Commeasure answered 11/3, 2015 at 14:16 Comment(5)
AJF : Did you tried it?Stirrup
@user3560140 Yes. Your command simply shows a list of parameter options and I tried a few. They show TCP ports LISTENING but I believe that is already being used and cannot see a free port. Would the status of a free port be "FREE" or "OPEN" or what?Commeasure
Add -p to that,it will show the process that opened the port: netstat -antup,whatever is not in use is FREE :)Stirrup
@user3560140 Thanks for further feedback. I tried netstat -antup and netstat -lntup and both just provided a list of parameter options as before. So I tried netstat -antp and it stated "Active Connections" and an empty list with the column headings of "Proto", "Local Address", "Foreign Address", "State" and "Off Load State". But as I said it listed no connectionsCommeasure
For what purpose? If you just want to listen on an arbitrary port, bind to port 0 and use getsockname() to find out what port the OS gave you.Gally
S
7

netstat -lntu

This will solve your purpose.

Stirrup answered 11/3, 2015 at 14:22 Comment(2)
This command will list open network ports and the processes that own them. Visit : superuser.com/a/529831/881022Ceaseless
That's not what the OP asked. He wants an available port :)Graber
M
7

Inspired by https://gist.github.com/lusentis/8453523

Start with a seed port, and increment it till it is usable

BASE_PORT=16998
INCREMENT=1

port=$BASE_PORT
isfree=$(netstat -taln | grep $port)

while [[ -n "$isfree" ]]; do
    port=$[port+INCREMENT]
    isfree=$(netstat -taln | grep $port)
done

echo "Usable Port: $port"
Marrin answered 7/8, 2017 at 3:42 Comment(0)
M
4

In Bash you can write simple for loop to check which TCP ports are free, e.g.

$ for i in {1..1024}; do (exec 2>&-; echo > /dev/tcp/localhost/$i && echo $i is open); done
22 is open
25 is open
111 is open
587 is open
631 is open
841 is open
847 is open
1017 is open
1021 is open

For more info, check: Advanced Bash-Scripting Guide: Chapter 29. /dev and /proc

Mensurable answered 11/2, 2016 at 12:2 Comment(2)
Should this work on mac? It completed without returning any output for meWolof
this shows the opposite to me: just the busy onesOnetoone
C
0

Building on the answer by @Fengzmg:

This implementation:

  • uses the newer ss instead of netstat
  • doesn't rely on grep-ing the output, instead we use the filter interface in ss
  • is more robust because:
    • we only match the source port (sport), instead of the grep approach that would match destination ports
    • better support for ports that have fewer than 5 digits as we won't match substrings. The grep approach would match 443 in 30443.

Note: the -4 restricts to only IPv4. There's also -6 but you can not specify either to match on both.

BASE_PORT=1234
INCREMENT=1

port=$BASE_PORT

while [ -n "$(ss -tan4H "sport = $port")" ]; do
  port=$((port+INCREMENT))
done

echo "Usable Port: $port"
Coumarone answered 8/3 at 2:13 Comment(1)
That's a good one :)Graber

© 2022 - 2024 — McMap. All rights reserved.