Sockets: Discover port availability using Java

JavaSocketsPort

Java Problem Overview


How do I programmatically determine the availability of a port in a given machine using Java?

i.e given a port number, determine whether it is already being used or not?.

Java Solutions


Solution 1 - Java

This is the implementation coming from the Apache camel project:

/**
 * Checks to see if a specific port is available.
 *
 * @param port the port to check for availability
 */
public static boolean available(int port) {
    if (port < MIN_PORT_NUMBER || port > MAX_PORT_NUMBER) {
        throw new IllegalArgumentException("Invalid start port: " + port);
    }

    ServerSocket ss = null;
    DatagramSocket ds = null;
    try {
        ss = new ServerSocket(port);
        ss.setReuseAddress(true);
        ds = new DatagramSocket(port);
        ds.setReuseAddress(true);
        return true;
    } catch (IOException e) {
    } finally {
        if (ds != null) {
            ds.close();
        }

        if (ss != null) {
            try {
                ss.close();
            } catch (IOException e) {
                /* should not be thrown */
            }
        }
    }

    return false;
}

They are checking the DatagramSocket as well to check if the port is avaliable in UDP and TCP.

Hope this helps.

Solution 2 - Java

For Java 7 you can use try-with-resource for more compact code:

private static boolean available(int port) {
    try (Socket ignored = new Socket("localhost", port)) {
        return false;
    } catch (IOException ignored) {
        return true;
    }
}

Solution 3 - Java

It appears that as of Java 7, David Santamaria's answer doesn't work reliably any more. It looks like you can still reliably use a Socket to test the connection, however.

private static boolean available(int port) {
	System.out.println("--------------Testing port " + port);
    Socket s = null;
    try {
    	s = new Socket("localhost", port);
    	
        // If the code makes it this far without an exception it means
        // something is using the port and has responded.
        System.out.println("--------------Port " + port + " is not available");
        return false;
    } catch (IOException e) {
    	System.out.println("--------------Port " + port + " is available");
    	return true;
    } finally {
        if( s != null){
        	try {
                s.close();
            } catch (IOException e) {
                throw new RuntimeException("You should handle this error." , e);
            }
        }
    }
}

Solution 4 - Java

If you're not too concerned with performance, you could always try listening on a port using the ServerSocket class. If it throws an exception odds are it's being used.

public static boolean isAvailable(int portNr) {
  boolean portFree;
  try (var ignored = new ServerSocket(portNr)) {
      portFree = true;
  } catch (IOException e) {
      portFree = false;
  }
  return portFree;
}

EDIT: If all you're trying to do is select a free port then new ServerSocket(0) will find one for you.

Solution 5 - Java

The following solution is inspired by the SocketUtils implementation of Spring-core (Apache license).

Compared to other solutions using Socket(...) it is pretty fast (testing 1000 TCP ports in less than a second).

Of course it can only detect services that open a port on all interfaces or that explicitly run on localhost.

public static boolean isTcpPortAvailable(int port) {
	try (ServerSocket serverSocket = new ServerSocket()) {
        // setReuseAddress(false) is required only on OSX, 
        // otherwise the code will not work correctly on that platform			
        serverSocket.setReuseAddress(false);
		serverSocket.bind(new InetSocketAddress(InetAddress.getByName("localhost"), port), 1);
		return true;
	} catch (Exception ex) {
		return false;
	}
}       

Solution 6 - Java

The try/catch socket based solutions , might not yield accurate results (the socket address is "localhost" and in some cases the port could be "occupied" not by the loopback interface and at least on Windows I've seen this test fails i.e. the prot falsely declared as available).

There is a cool library named SIGAR , the following code can hook you up :

Sigar sigar = new Sigar();
int flags = NetFlags.CONN_TCP | NetFlags.CONN_SERVER | NetFlags.CONN_CLIENT;             NetConnection[] netConnectionList = sigar.getNetConnectionList(flags);
for (NetConnection netConnection : netConnectionList) {
   if ( netConnection.getLocalPort() == port )
        return false;
}
return true;

Solution 7 - Java

A cleanup of the answer pointed out by David Santamaria:

/**
 * Check to see if a port is available.
 *
 * @param port
 *            the port to check for availability.
 */
public static boolean isPortAvailable(int port) {
    try (var ss = new ServerSocket(port); var ds = new DatagramSocket(port)) {
        return true;
    } catch (IOException e) {
        return false;
    }
}

This is still subject to a race condition pointed out by user207421 in the comments to David Santamaria's answer (something could grab the port after this method closes the ServerSocket and DatagramSocket and returns).

Solution 8 - Java

In my case it helped to try and connect to the port - if service is already present, it would respond.

    try {
        log.debug("{}: Checking if port open by trying to connect as a client", portNumber);
        Socket sock = new Socket("localhost", portNumber);			
        sock.close();
        log.debug("{}: Someone responding on port - seems not open", portNumber);
        return false;
    } catch (Exception e) {			
        if (e.getMessage().contains("refused")) {
            return true;
    }
        log.error("Troubles checking if port is open", e);
        throw new RuntimeException(e);				
    }

Solution 9 - Java

In my case I had to use DatagramSocket class.

boolean isPortOccupied(int port) {
    DatagramSocket sock = null;
    try {
        sock = new DatagramSocket(port);
        sock.close();
        return false;
    } catch (BindException ignored) {
        return true;
    } catch (SocketException ex) {
        System.out.println(ex);
        return true;
    }
}

Don't forget to import first

import java.net.DatagramSocket;
import java.net.BindException;
import java.net.SocketException;

Solution 10 - Java

I have Tried something Like this and it worked really fine with me

            Socket Skt;
	        String host = "localhost";
	        int i = 8983; // port no.
		      
		         try {
		            System.out.println("Looking for "+ i);
		            Skt = new Socket(host, i);
		            System.out.println("There is a Server on port "
		            + i + " of " + host);
		         }
		         catch (UnknownHostException e) {
		            System.out.println("Exception occured"+ e);
		           
		         }
		         catch (IOException e) {
		        	 System.out.println("port is not used");
		        	 
		         }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser54075View Question on Stackoverflow
Solution 1 - JavaDavid SantamariaView Answer on Stackoverflow
Solution 2 - JavaeivindwView Answer on Stackoverflow
Solution 3 - JavaTwentyMilesView Answer on Stackoverflow
Solution 4 - JavaSpencer RuportView Answer on Stackoverflow
Solution 5 - JavaJMaxView Answer on Stackoverflow
Solution 6 - JavaShmil The CatView Answer on Stackoverflow
Solution 7 - JavaLuke HutchisonView Answer on Stackoverflow
Solution 8 - JavaIvanView Answer on Stackoverflow
Solution 9 - JavakmchmkView Answer on Stackoverflow
Solution 10 - Javamayu jadhvView Answer on Stackoverflow