Как определить состояние сервера в реализации Java сканера портов - PullRequest
1 голос
/ 06 мая 2010

Я пишу сканер портов на Java и хочу выделить следующие 4 варианта использования:

  • порт открыт
  • порт открыт, а баннер сервера прочитан
  • порт закрыт
  • сервер не работает

У меня есть следующий код:

    InetAddress address = InetAddress.getByName("google.com");
    int[] ports = new int[]{21, 22, 23, 80, 443};
    for (int i = 0; i < ports.length; i++) {
        int port = ports[i];
        Socket socket = null;
        try {
            socket = new Socket(address, port);
            socket.setSoTimeout(500);
            System.out.println("port " + port + " open");
            BufferedReader reader = new BufferedReader(
                 new InputStreamReader(socket.getInputStream()));
            String line = reader.readLine();
            if (line != null) {
                System.out.println(line);
            }
            socket.close();
        } catch (SocketTimeoutException ex) {
            // port was open but nothing was read from input stream
            ex.printStackTrace();
        } catch (ConnectException ex) {
            // port is closed
            ex.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (socket != null && !socket.isClosed()) {
                try {
                    socket.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

Проблема в том, что я получаю исключение ConnectionException как при закрытии порта, так и при недоступности сервера, но с другим сообщением об исключении:

java.net.ConnectException: Тайм-аут соединения: соединение

когда соединение никогда не было установлено и

java.net.ConnectException: В соединении отказано: соединиться

когда порт был закрыт

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

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

socket = new Socket();
socket.setSoTimeout(500);
socket.connect(new InetSocketAddress(address, port), 1000);

У меня та же проблема, но с исключением SocketTimeoutException. Я получаю

java.net.SocketTimeoutException: Тайм-аут чтения

если порт был открыт, но не было баннера для чтения и

java.net.SocketTimeoutException: истекло время ожидания соединения

если сервер не работает или порт закрыт.

Есть идеи? Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 06 мая 2010

Не думаю, что у вас есть какие-либо опции, кроме разбора сообщения об исключении. Есть ли причина, по которой вы не хотите этого делать?

0 голосов
/ 08 мая 2011

ConnectException имеет только пустой конструктор и конструктор errorMesssage. В API нет подклассов ConnectException. Поэтому я боюсь, что Java не может правильно определить причину. Парсинг сообщения об исключении кажется единственным способом, несмотря на то, что он очень запутан с переводами.

...