端口扫描程序

端口扫描程序

If you need 200ms for each of the 65536 ports (in the worst case, a firewall is blocking everything, thus making you hit your timeout for every single port), the maths is pretty simple: you need 13k seconds, or about 3 hours and a half.

You have 2 (non-exclusive) options to make it faster:
  • reduce your timeout
  • paralellize your code
Since the operation is I/O bound (in contrast to CPU bound -- that is, you spend time waiting for I/O, and not for some huge calculation to complete), you can use many, many threads. Try starting with 20. They would divide the 3 hours and a half among them, so the maximum expected time is about 10 minutes. Just remember that this will put pressure on the other side, ie, the scanned host will see huge network activity with "unreasonable" or "strange" patterns, making the scan extremely easy to detect.

The easiest way (ie, with minimal changes) is to use the ExecutorService and Future APIs: @import url(http://www.blogjava.net/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

public  static Future<Boolean> portIsOpen( final ExecutorService es,  final String ip,  final  int port,  final  int timeout) {
   return es.submit( new Callable<Boolean>() {
      @Override  public Boolean call() {
         try {
          Socket socket =  new Socket();
          socket.connect( new InetSocketAddress(ip, port), timeout);
          socket.close();
           return  true;
        }  catch (Exception ex) {
           return  false;
        }
      }
   });
}


Then, you can do something like:

public  static  void main( final String  args) {
   final ExecutorService es = Executors.newFixedThreadPool(20);
   final String ip = "127.0.0.1";
   final  int timeout = 200;
   final List<Future<Boolean>> futures =  new ArrayList<>();
   for ( int port = 1; port <= 65535; port++) {
    futures.add(portIsOpen(es, ip, port, timeout));
  }
  es.shutdown();
   int openPorts = 0;
   for ( final Future<Boolean> f : futures) {
     if (f.get()) {
      openPorts++;
    }
  }
  System.out.println("There are " + openPorts + " open ports on host " + ip + " (probed with a timeout of " + timeout + "ms)");
}


If you need to know which ports are open (and not just how many, as in the above example), you'd need to change the return type of the function to Future<SomethingElse>, where SomethingElse would hold the port and the result of the scan, something like:

public  final  class ScanResult {
   private  final  int port;
   private  final  boolean isOpen;
   //  constructor
  
//  getters
}


Then, change Boolean to ScanResult in the first snippet, and return new ScanResult(port, true) or new ScanResult(port, false) instead of just true or false





你可能感兴趣的:(端口扫描程序)