¿Cómo puedo detectar el estado del servidor en una aplicación java escáner de puertos
-
03-10-2019 - |
Pregunta
Estoy escribiendo un escáner de puertos en Java y quiero ser capaz de distinta siguiendo los 4 casos de uso:
- puerto está abierto
- puerto se fue leído bandera abierta y el servidor
- puerto está cerrado
- servidor no está vivo
Tengo el siguiente código:
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();
}
}
}
}
El problema es que tengo un ConnectionException tanto cuando el puerto está cerrado y el servidor no puede ser alcanzado, pero con un mensaje de excepción diferente:
java.net.ConnectException: conexión agotado: connect
cuando la conexión nunca se estableció y
java.net.ConnectException: Conexión rechazada: connect
cuando el puerto estaba cerrado
por lo que no puede hacer la distinción entre los dos casos de uso sin cavar en el mensaje de excepción real.
Lo mismo sucede cuando intento un enfoque diferente para la creación de socket. Si uso:
socket = new Socket();
socket.setSoTimeout(500);
socket.connect(new InetSocketAddress(address, port), 1000);
Tengo el mismo problema pero con la SocketTimeoutException lugar. Llego a
java.net.SocketTimeoutException: Leer tiempo de espera
si el puerto estaba abierta pero no había ninguna bandera para ser leído y
java.net.SocketTimeoutException: Conectar tiempo de espera
si el servidor no está vivo o puerto está cerrado.
Algunas ideas? Gracias de antemano!
Solución
No creo que tiene alguna opciones además de analizar el mensaje de excepción. ¿Hay una razón por la que prefiere no hacer esto?
Otros consejos
ConnectException sólo tiene un constructor vacío y un constructor de errorMesssage. No hay subclases de ConnectException en la API. Así que me temo, Java no hay manera apropiada para acceder a la razón. Analizar el mensaje de excepción parece ser la única manera, a pesar de ser muy sucia con traducciones.