How to find an available port?
Solution 1
If you don't mind the port used, specify a port of 0 to the ServerSocket constructor and it will listen on any free port.
ServerSocket s = new ServerSocket(0);
System.out.println("listening on port: " + s.getLocalPort());
If you want to use a specific set of ports, then the easiest way is probably to iterate through them until one works. Something like this:
public ServerSocket create(int[] ports) throws IOException {
for (int port : ports) {
try {
return new ServerSocket(port);
} catch (IOException ex) {
continue; // try next port
}
}
// if the program gets here, no port in the range was found
throw new IOException("no free port found");
}
Could be used like so:
try {
ServerSocket s = create(new int[] { 3843, 4584, 4843 });
System.out.println("listening on port: " + s.getLocalPort());
} catch (IOException ex) {
System.err.println("no available ports");
}
Solution 2
If you pass 0 as the port number to the constructor of ServerSocket, It will allocate a port for you.
Solution 3
Starting from Java 1.7 you can use try-with-resources like this:
private Integer findRandomOpenPortOnAllLocalInterfaces() throws IOException {
try (
ServerSocket socket = new ServerSocket(0);
) {
return socket.getLocalPort();
}
}
If you need to find an open port on a specific interface check ServerSocket documentation for alternative constructors.
Warning: Any code using the port number returned by this method is subject to a race condition - a different process / thread may bind to the same port immediately after we close the ServerSocket instance.
Solution 4
According to Wikipedia, you should use ports 49152
to 65535
if you don't need a 'well known' port.
AFAIK the only way to determine wheter a port is in use is to try to open it.
Solution 5
If you need in range use:
public int nextFreePort(int from, int to) {
int port = randPort(from, to);
while (true) {
if (isLocalPortFree(port)) {
return port;
} else {
port = ThreadLocalRandom.current().nextInt(from, to);
}
}
}
private boolean isLocalPortFree(int port) {
try {
new ServerSocket(port).close();
return true;
} catch (IOException e) {
return false;
}
}
Related videos on Youtube
Roman
Updated on May 06, 2022Comments
-
Roman almost 2 years
I want to start a server which listen to a port. I can specify port explicitly and it works. But I would like to find a port in an automatic way. In this respect I have two questions.
In which range of port numbers should I search for? (I used ports 12345, 12346, and 12347 and it was fine).
How can I find out if a given port is not occupied by another software?
-
Cezar Terzian almost 4 yearsif the port is occupied by another software the code will throw an IOException
-
jonescb about 14 yearsDon't know who voted you down, but I voted you back up. You could set up a recursive function to tries to setup the ServerSocket, and if you get an IOException (or whatever it is), you try again until it successfully gets a port.
-
Roman about 14 yearsI thinks it's better to check if a port is available and then try to start listening to this port. It's does not seem to be elegant to start something and then find out that there are some problem and then try to solve these problems.
-
Roman about 14 yearsYes, I think it's the most elegant solution but because of some reasons it does not work in my case. But I still need to find out what exactly is wrong.
-
FrustratedWithFormsDesigner about 14 years@Roman: Why doesn't it work? Update your question to include this (or people will keep suggesting it) and explain why this solution fails for you.
-
rmeador about 14 yearsthere is a similar (and more complete, IIRC) list that comes as part of nmap. +1
-
OscarRyz about 14 years@Roman well, yes, that would be better, except for the fact there is no a method to know if a port is available. If
new ServerSocket(0)
is not working for your the alternative is this. I think there are 85% of possibilities you end up using my suggestion. -
vorburger over 11 yearsWhen using new ServerSocket(0), care should be taken to close it! Based on javasourcecode.org/html/open-source/eclipse/eclipse-3.5.2/org/…, slightly adapted in my gist.github.com/3429822
-
Graham Edgecombe over 11 years@vorburger, doing it in that manner is prone to race conditions. It's nicer to just listen on the server socket immediately, rather than open it to find a free port, close it again, and then open one again on the free port (by which time there is a small chance something else is now listening on that port.)
-
vorburger over 11 yearsagreed, but it depends on the exact use case: In my case I needed to find a free port number to hand it into some API (say an embedded Jetty starter, for tests) - the respective API wants a socket number - not an already opened server socket. So it depends.
-
Joker_vD almost 10 years@vorburger Reasonable APIs will accept zero as a valid port number to listen on, and then will tell you the actual port being listened on. Hovewer, there are not many reasonable APIs: many programs specifically test for 0 port being passed and refuse it (
ssh -D 127.0.0.0:0 ...
? Nope!), which is really frustrating. We had to patch quite a number of libraries/programs to make them of use to us. -
KevinL about 9 yearsLooking at Eclipse's code, they do the same thing as Graham Edgecombe's answer
-
David Ehrmann almost 9 yearsThis might not work if you don't set
SO_REUSEADDR
. And there's a race condition, but it's hard to fix that. -
Vlad Ilie about 8 yearswas wondering how to check a port, then unbind from it. Thanks SergeyB!
-
Simon Kissane over 7 yearsIf every port in the range [from,to) is in use, this code will loop infinitely (or at least until one of those ports becomes free). If you do a sequential scan rather than picking ports in the range at random, you can avoid this possibility (just throw an exception when you get to the end of the range without finding a free port). If you really need to pick ports at random, then you need a set to keep track of the ports you've tried so far, and then raise an error when the size of that set equals to - from.
-
user207421 about 7 years@vorburger When using any port, care should be taken to close it.
new ServerSocket(0)
is not different in this respect. There is nothing whatsoever in your first link about this. Your second link merely exhibits poor practice. Once you've constructed theServerSocket
you should use it, not close it and try to reuse the same port number. All that is a complete waste of time, as well as being vulnerable to timing-window problems. -
user207421 about 7 yearsThis might not work if you subsequently try to open another
ServerSocket
with the same port number, as it might have been taken in the meanwhile. Why you wouldn't just return the actualServerSocket
instead of closing it remains a mystery. -
OzgurH over 6 years+1. Since Wikipedia is not always the source of absolute truth/facts, I thought it may be useful to note that, the reference for that Wikipedia page comes from "Internet Assigned Numbers Authority (IANA)"s "[Service Name and Transport Protocol Port Number Registry(iana.org/assignments/service-names-port-numbers/…" page, based on RFC 6335 - Section 6 (i.e. "Solid" reference in this case! :) ).
-
khm about 6 yearsIf the server is listening on a random port like this, how does the client know which port to send to? I tried this, but realized that the Socket() constructor on the client side needs a specific port to send to.
-
Captain Man almost 6 years@EJP Sometimes third party code accepts a port but not the socket itself.
-
ed22 almost 6 yearsHow do I find this port from client? ;)
-
user207421 over 4 yearsPort 0 is considerably simpler and doesn't require creating two
ServerSockets
in the success case, and doesn't suffer from the timing-window problems of this code. -
user207421 over 4 years@khm It doesn't. That's why the question doesn't make sense. This answer answers the question, but the whole situation is untenable.
-
user207421 over 4 years@CaptainMan Sure, but in those cases the port is surely assumed to be preallocated. A dynamically allocated port has to be supplied to clients by some other mechanism such as a naming service or a broadcast or mulitcast. The whole question here is malformed.
-
user207421 over 4 yearsThis code keeps opening and leaking
ServerSockets
forever and only retains the last one that succeeded. It needs abreak
statement. -
Captain Man over 4 years@user207421 You can't change third party code to accept a
ServerSocket
instead of anint
for the port though. -
Alexey Berezkin over 4 yearsFor those who is curious, under the hood
SpringUtils.findAvailableTcpPort()
is doing exactly the same recommended in other answers: pick a port then trynew ServerSocket(port)
. -
Graeme Moss almost 4 yearsMy use case is worse in that I know multiple JVMs will use the same code to find their own free port at the same time, and it seems there's some likelyhood in them picking the same port via port 0 (or I was very unlucky), increasing the chance of a race hazard during the time between closing the port and handing it to the API to be used. Maybe picking a random number like @Serhii Bohutskyi suggests is better for me.
-
khmarbaise about 2 yearsSocketUtils has been marked deprecated for Spring Boot (Spring version?) 2.6.X...
-
RamPrakash almost 2 yearsIt is deprecated!!