How to find an available port?
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");
}
If you pass 0 as the port number to the constructor of ServerSocket, It will allocate a port for you.
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.
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.
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;
}
}