Найти свободный порт на Java - PullRequest
0 голосов
/ 29 июня 2018

Мне нужно найти свободный порт в приложении Java. Почему не работает приведенный ниже код? Всегда возвращает 0.

public int findFreePort() {
    int portNumber = new InetSocketAddress(0).getPort();
    return portNumber;
}

Java документ new InetSocketAddress() говорит:

Создает адрес сокета, где IP-адрес - это подстановочный адрес, а номер порта - указанное значение.

Допустимое значение порта - от 0 до 65535. Нулевой номер порта позволит системе выбрать эфемерный порт в операции связывания.

1 Ответ

0 голосов
/ 29 июня 2018

На самом деле вы выводите член порта, который вы указали в конструкторе. Так что 0 ожидается.
Javadoc утверждает, что порт позволит системе выбрать временный порт для операции привязки. Это не говорит о том, что номер порта будет оцениваться с эфемерным портом непосредственно в экземпляре InetSocketAddress. На самом деле вы не выполняете операцию привязки с этим экземпляром InetSocketAddress.
Ясно, что вы не открыли / не создали канал сокета для связи с этим экземпляром. Таким образом, вы не можете заметить результат порта.

Например, это связывает a ServerSocket с InetSocketAddress:

ServerSocket ss = new ServerSocket(..);
ss.bind(new InetSocketAddress(0));

Вот более полный пример, иллюстрирующий, как все работает:

public class InetSockerAddressWithEphemeralPortMain {

    public static void main(String[] args) throws InterruptedException, IOException {
        InetSocketAddress randomSocketAddressFirst = new InetSocketAddress(0);

        try (ServerSocket ssOne = new ServerSocket()) {
            System.out.println("randomSocketAddress port before any binding : " + randomSocketAddressFirst.getPort());
            ssOne.bind(randomSocketAddressFirst);
            System.out.println("local port after first binding :" + ssOne.getLocalPort());
        }

        try (ServerSocket ssTwo = new ServerSocket()) {
            ssTwo.bind(randomSocketAddressFirst);
            System.out.println("local port after second binding :" + ssTwo.getLocalPort());
            System.out.println("randomSocketAddress port after all bindings : " + randomSocketAddressFirst.getPort());
        }

    }
}

Выход:

порт randomSocketAddress перед любой привязкой: 0

локальный порт после первой привязки: 65110

локальный порт после второй привязки: 65111

порт randomSocketAddress после всех привязок: 0

Вы можете видеть, что объект InetSocketAddress всегда сохраняет 0 как значение порта, в то время как объекты ServerSocket извлекают выгоду из подобранного эфемерного порта.

...