Come faccio a rilevare lo stato del server in un'implementazione Java port scanner
-
03-10-2019 - |
Domanda
Sto scrivendo un port scanner in Java e voglio essere in grado di distinguere i casi di utilizzo seguenti 4:
- porta è aperta ??li>
- porta è aperta e server di bandiera è stato letto
- porta è chiusa
- server non è in diretta ??li>
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 ??strong>
se la porta era aperta, ma non c'era bandiera da leggere e
java.net.SocketTimeoutException: Connetti scaduta ??strong>
se il server non è in diretta o la porta è chiusa.
Tutte le idee? Grazie in anticipo!
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.