10

I have the need to discover open ports on a remote server. I'm wondering if this is possible. I was thinking I'd open a socket, and if this succeeds, it means that it's used ... otherwise, if I get an exception, then it is not used.

For example,

public boolean isActive() {
    Socket s = null;
    try {
        s = new Socket();
        s.setReuseAddress(true);
        SocketAddress sa = new InetSocketAddress(this.host, this.port);
        s.connect(sa, 3000);
        return true;
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (s != null) {
            try {
                s.close();
            } catch (IOException e) {
            }
        }
    }
    return false;
}

is this a viable approach?

Alfergon
  • 5,463
  • 6
  • 36
  • 56
Jeffrey Blattman
  • 22,176
  • 9
  • 79
  • 134
  • possible duplicate of [Sockets: Discover port availability using Java](http://stackoverflow.com/questions/434718/sockets-discover-port-availability-using-java) – hcarrasko Mar 02 '15 at 18:14
  • 3
    @Hector The answers on that question are mostly about testing whether something is bound to a port locally. This question is about a remote system. – Kenster Mar 02 '15 at 19:40
  • 1
    I think @Alain Pannetier answer should be the accepted one. – Alfergon Jan 18 '17 at 13:28

2 Answers2

20

FWIW, a Java solution I use from times to times (better than telnet: supports timeout).

package com.acme.util;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

public class CheckSocket {

    public static void main(String[] args) {
        int exitStatus = 1 ;
        if (args.length != 3) {
            System.out.println("Usage: CheckSocket node port timeout");
        } else {
            String node = args[0];
            int port = Integer.parseInt(args[1]);
            int timeout = Integer.parseInt(args[2]);

            Socket s = null;
            String reason = null ;
            try {
                s = new Socket();
                s.setReuseAddress(true);
                SocketAddress sa = new InetSocketAddress(node, port);
                s.connect(sa, timeout * 1000);
            } catch (IOException e) {
                if ( e.getMessage().equals("Connection refused")) {
                    reason = "port " + port + " on " + node + " is closed.";
                };
                if ( e instanceof UnknownHostException ) {
                    reason = "node " + node + " is unresolved.";
                }
                if ( e instanceof SocketTimeoutException ) {
                    reason = "timeout while attempting to reach node " + node + " on port " + port;
                }
            } finally {
                if (s != null) {
                    if ( s.isConnected()) {
                        System.out.println("Port " + port + " on " + node + " is reachable!");
                        exitStatus = 0;
                    } else {
                        System.out.println("Port " + port + " on " + node + " is not reachable; reason: " + reason );
                    }
                    try {
                        s.close();
                    } catch (IOException e) {
                    }
                }
            }
        }
        System.exit(exitStatus);
    }
}
Alain Pannetier
  • 9,315
  • 3
  • 41
  • 46
3

Does this have to be done in Java? There are tools for that (Nmap). Else, your method will "work" but I'm not sure how useful this will be.

Be warned, firewalls can do some tricky things. Such as allow the connections to establish but do nothing with it so it appears as if the port is open but the firewall is actually blocking all traffic. Or, some ports will only be open to requests from a certain IP range, subnet, or physical device.

Andrew White
  • 52,720
  • 19
  • 113
  • 137
  • 1
    thanks. it's our server, and we control the firewall. we have an application that establishes reverse port forwards to the server. we have a service that tracks port in use, but we still need the above as a failsafe in case the service gets out of sync with the actual ports. – Jeffrey Blattman Mar 08 '11 at 02:09