Domanda

Sto scrivendo un port scanner in Java e voglio essere in grado di distinguere i casi di utilizzo seguenti 4:

  • porta è aperta
  • porta è aperta e server di bandiera è stato letto
  • porta è chiusa
  • server non è in diretta

Ho il seguente codice:

    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();
                }
            }
        }
    }

Il problema è che ho un ConnectionException sia quando la porta è chiusa e il server non può essere raggiunto, ma con un messaggio di eccezione diversa:

java.net.ConnectException: Connessione scaduta: connect

quando la connessione non è mai stata stabilita e

java.net.ConnectException: Connection refused: connect

quando la porta è stata chiusa

quindi non posso fare la distinzione tra i due casi d'uso senza scavare nel messaggio di eccezione effettivo.

Stessa cosa succede quando si tenta un approccio diverso per la creazione del socket. Se uso:

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

Ho lo stesso problema, ma con il SocketTimeoutException invece. Ho un

java.net.SocketTimeoutException: Leggi scaduta

se la porta era aperta, ma non c'era bandiera da leggere e

java.net.SocketTimeoutException: Connetti scaduta

se il server non è in diretta o la porta è chiusa.

Tutte le idee? Grazie in anticipo!

È stato utile?

Soluzione

Non credo avete opzioni oltre l'analisi del messaggio di eccezione. C'è una ragione si preferisce non fare questo?

Altri suggerimenti

ConnectException ha solo uno vuoto, e un costruttore errorMesssage. Non ci sono sottoclassi di ConnectException nell'API. Quindi temo, Java non fa modo corretto per accedere alla ragione. L'analisi del messaggio di eccezione sembra essere l'unico modo, nonostante sia davvero disordinato con traduzioni.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top