Как программно определить доступность порта на данном компьютере с помощью Java?
Если задан номер порта, определите, будет ли он уже использоваться или нет?
Как программно определить доступность порта на данном компьютере с помощью Java?
Если задан номер порта, определите, будет ли он уже использоваться или нет?
Это реализация, исходящая из Apache camel проект:
/**
 * 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;
}
Они также проверяют DatagramSocket, чтобы проверить, доступен ли порт в UDP и TCP.
Надеюсь, что это поможет.
Для Java 7 вы можете использовать try-with-resource для более компактного кода:
private static boolean available(int port) {
    try (Socket ignored = new Socket("localhost", port)) {
        return false;
    } catch (IOException ignored) {
        return true;
    }
}
		Похоже, что с Java 7, ответ David Santamaria больше не работает надежно. Похоже, вы все же можете надежно использовать Socket для проверки соединения.
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);
            }
        }
    }
}
		Если вы не слишком озабочены производительностью, вы всегда можете попробовать прослушивать порт, используя класс ServerSocket. Если он генерирует исключение, то шансы его использования.
public static boolean isAvailable(int portNr) {
  boolean portFree;
  try (var ignored = new ServerSocket(portNr)) {
      portFree = true;
  } catch (IOException e) {
      portFree = false;
  }
  return portFree;
}
  РЕДАКТИРОВАТЬ: Если все, что вы пытаетесь сделать, это выбрать свободный порт, то new SocketServer(0) найдет один для вас.
Следующее решение основано на реализации Spring-core SocketUtils (лицензия Apache).
 По сравнению с другими решениями, использующими Socket(...) это довольно быстро (тестирование 1000 портов TCP менее чем за секунду):
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;
    }
}       
		Решения на основе сокета try/catch могут не дать точных результатов (адрес сокета - "localhost", и в некоторых случаях порт может быть "занят" не интерфейсом loopback, и, по крайней мере, в Windows я видел, что этот тест не выполняется, т.е. против ложно объявлен как доступный).
Существует классная библиотека под названием SIGAR, следующий код может вас поднять:
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;
		В моем случае это помогло подключиться к порту - если служба уже присутствует, он ответил бы.
    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);              
    }
		В моем случае мне пришлось использовать класс DatagramSocket.
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;
    }
}
Не забывайте сначала импортировать
import java.net.DatagramSocket;
import java.net.BindException;
import java.net.SocketException;
		Уборка ответа, на который указал Дэвид Сантамария:
/**
 * Check to see if a port is available.
 *
 * @param port
 *            the port to check for availability.
 */
public static boolean portIsAvailable(int port) {
    try (var ss = new ServerSocket(port); var ds = new DatagramSocket(port)) {
        return true;
    } catch (IOException e) {
        return false;
    }
}
  Это все еще зависит от состояния гонки, указанного пользователем 207421 в комментариях к ответу Дэвида Сантамарии (что-то может захватить порт после того, как этот метод закроет ServerSocket и DatagramSocket и вернется).
Я пробовал что-то вроде этого, и это сработало очень хорошо со мной
            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");
                 }
		Некоторые из этих ответов здесь не дали правильных результатов, и тот, который помогло, использовал этот класс:
https://mina.apache.org/mina-project/apidocs/org/apache/mina/util/AvailablePortFinder.html