views:

64

answers:

1

I am writing a port scanner in Java and I want to be able to distinct the following 4 use cases:

  • port is open
  • port is open and server banner was read
  • port is closed
  • server is not live

I have the following code:

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

The problem is that I get a ConnectionException both when the port is closed and the server cannot be reached but with a different exception message:

java.net.ConnectException: Connection timed out: connect

when the connection was never established and

java.net.ConnectException: Connection refused: connect

when the port was closed

so I cannot make the distinction between the two use cases without digging into the actual exception message.

Same thing happens when I try a different approach for the socket creation. If I use:

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

I have the same problem but with the SocketTimeoutException instead. I get a

java.net.SocketTimeoutException: Read timed out

if port was open but there was no banner to be read and

java.net.SocketTimeoutException: connect timed out

if server is not live or port is closed.

Any ideas? Thanks in advance!

A: 

I don't think you have any options besides parsing the exception message. Is there a reason you'd rather not do this?

Sugerman
I think it's a little "dirty" to count on String message to decide on what's happening so I would prefer not to go for that. I was just wondering if there was another option I didn't know about.
akz