2

私は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:接続がタイムアウトしました

サーバーが稼働していないか、ポートが閉じている場合。

何か案は?前もって感謝します!

4

2 に答える 2

1

例外メッセージを解析する以外にオプションはないと思います。これをしたくない理由はありますか?

于 2010-05-06T05:41:28.397 に答える
0

ConnectExceptionには、空のコンストラクターと errorMesssage コンストラクターしかありません。API には ConnectException のサブクラスはありません。残念ながら、Java にはその理由にアクセスする適切な方法がありません。例外メッセージを解析することが唯一の方法のようですが、翻訳が非常に面倒です。

于 2011-05-08T10:14:50.543 に答える