Я пишу сканер портов на 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: истекло время ожидания соединения
если сервер не работает или порт закрыт.
Есть идеи? Заранее спасибо!