Как я могу найти открытые порты в диапазоне портов? - PullRequest
8 голосов
/ 22 августа 2011

Я хочу найти открытый локальный порт в некотором диапазоне.

Как я могу сделать это наиболее эффективным способом, без подключения к порту.

Ответы [ 7 ]

6 голосов
/ 22 августа 2011

Если вы хотите найти локальный открытый порт для привязки к серверу, то вы можете создать ServerSocket, и если он не выбрасывает исключение, тогда он открыт.

В одном из моих проектов я сделал следующее:

private int getAvailablePort() throws IOException {
    int port = 0;
    do {
        port = RANDOM.get().nextInt(20000) + 10000;
    } while (!isPortAvailable(port));

    return port;
}

private boolean isPortAvailable(final int port) throws IOException {
    ServerSocket ss = null;
    try {
        ss = new ServerSocket(port);
        ss.setReuseAddress(true);
        return true;
    } catch (final IOException e) {
    } finally {
        if (ss != null) {
            ss.close();
        }
    }

    return false;
}

RANDOM здесь ThreadLocal, но, конечно, вы можете делать там инкрементную часть.

3 голосов
/ 22 августа 2011

Есть небольшая проблема, с которой вы можете столкнуться в многозадачной среде Windows / Unix: если какой-либо isPortAvailable (последний порт int) из любого из ответов возвращает для вас значение true, это не значит, что в тот момент, когда вына самом деле связать это все еще будет доступно.Лучшим решением было бы создать метод

ServerSocket tryBind(int portRangeBegin, int portRangeEnd) throws UnableToBindException;

, чтобы вы просто запустили его и получили для вас открытый сокет на некотором доступном порту в заданном диапазоне.

1 голос
/ 22 августа 2011

Если вы имеете в виду порт на удаленном сервере, то вам может потребоваться библиотека, поддерживающая raw-сокет для отправки пакета синхронизации и ожидания пакета sync-ack, как это делает nmap .

0 голосов
/ 22 августа 2011

Просто передайте ноль в качестве номера порта новому ServerSocket (), и он найдет его для вас.Но вы можете забыть о диапазоне, он будет выбираться из диапазона, определенного системой.

0 голосов
/ 22 августа 2011

По сути та же идея, что и у Караси, но вместо создания такого количества сокетов, используйте InetSocketAddress и пытайтесь привязать ServerSocket к каждому адресу в диапазоне, пока не дойдете до открытого.

Если вы не хотите привязываться к этому порту (хотя, если вы этого не сделаете, сокет может также быть привязан в следующий момент после проверки), используйте обычный объект Socket и попробуйте подключиться к портам - если он работает, порт занят, если нет (и у вас нет брандмауэра, запрещающего соединение), то, скорее всего, он свободен.

0 голосов
/ 22 августа 2011

Если речь идет не о сниффинге портов, а об обнаружении сервисов, рассмотрите возможность использования сервера рандеву (например, сервера RMI) или протокола UDP.Когда-то мы использовали для этого JXTA, но я надеюсь, что сейчас есть лучшая альтернатива для этого.

0 голосов
/ 22 августа 2011

Один из способов сделать это - использовать некоторую собственную сетевую команду и проанализировать вывод.

  1. Вы можете попробовать команду netstat, поскольку она доступна на платформах Windows и * nix.
  2. Типичная команда будет netstat -n
  3. Вывод имеет следующий формат. Netstat command output

  4. вам нужно проанализировать столбец «Внешний адрес для localhost или 127.0.0.1» и получить список занятых портов. Затем посмотрите, находятся ли они в указанном вами диапазоне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...