¿Cómo puedo detectar el estado del servidor en una aplicación java escáner de puertos

StackOverflow https://stackoverflow.com/questions/2776729

  •  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!

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top