ポートスキャナーJavaの実装でサーバーステータスを検出するにはどうすればよいですか
-
03-10-2019 - |
質問
私は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: 接続は拒否:接続
ポートが閉じたとき
そのため、実際の例外メッセージを掘り下げることなく、2つのユースケースを区別することはできません。
ソケットの作成に対して別のアプローチを試してみると、同じことが起こります。使用する場合:
socket = new Socket();
socket.setSoTimeout(500);
socket.connect(new InetSocketAddress(address, port), 1000);
私は同じ問題を抱えていますが、代わりにsockettimeoutexceptionを使用しています。私は取得します
java.net.sockettimeoutexception: タイミングを読んでください
ポートが開いていたが、読むべきバナーがなかった場合、
java.net.sockettimeoutexception: タイミングで接続します
サーバーがライブでない場合 また ポートは閉じられています。
何か案は?前もって感謝します!
解決
例外メッセージを解析する以外に、あなたにはオプションがないと思います。あなたがこれをしたくない理由はありますか?
他のヒント
ConnectException 空のコンストラクターとエラーセージコンストラクターのみがあります。 APIには、ConnectExceptionのサブクラスはありません。だから私は恐れています、Javaは理由にアクセスする適切な方法をしません。例外メッセージを解析することは、翻訳が本当に厄介であるにもかかわらず、唯一の方法のようです。