English 中文(简体)
est港口的快速通道
原标题:Fastest way to scan ports with Java

我做了一个非常简单的港口扫描仪,但速度太慢,因此我想设法加快扫描速度。 我的守则是:

public boolean portIsOpen(String ip, int port, int timeout) {
    try {
        Socket socket = new Socket();
        socket.connect(new InetSocketAddress(ip, port), timeout);
        socket.close();
        return true;
    } catch (Exception ex) {
        return false;
    }
}

This code tests if a specific port is open on a specific ip. For timeout I used a minimum value of 200 because when I go lower it doesn t have enough time to test the port.

www.un.org/Depts/DGACM/index_spanish.htm 它运作良好,但从0到65535年难以扫描。 是否有任何其他办法可以在5分钟以内扫描0至65535?

最佳回答

如果你需要65536个港口中的每一个港口的200米(在最糟糕的情况下,防火墙阻挡了一切,使你打下了每个港口的停泊时间),那么数学就很简单:你需要13克秒,即大约3小时半。

你们有2项(非排他性)选择,以便更快地做到:

  • reduce your timeout
  • paralellize your code

由于这项行动是I/O约束(与CPU约束——即你花时间等待I/O,而不是进行一些大的计算来完成),你可以使用许多多管线<>。 从20开始。 它们将分三小时半,,预期的最大时间约为10分钟。 仅仅记住,这将给对方带来压力,即,被扫描的东道方会看到,网络活动具有“不合理”或“奇怪”模式,使扫描极易发现。

最为容易的方式(即,改动最小)是利用执行者服务和未来预报工具:

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

然后,你可以做这样的事情:

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

如果需要了解哪些港口开放<>? (而不仅仅是how many,如上所述,您需要将职能的返回类型改为。 (d) 未来设计;

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

然后,将<条码>改为<条码>。

EDIT:实际上,我刚刚注意到:在这种特殊情况下,你不需要斯堪的Result阶级来持有结果+港口,并且仍然知道哪一个港口是开放的。 由于你在<>List的<>上添加了未来,并且后来在上按你添加的的同一顺序处理这些未来,你可以有一个反响,即你在每一航程上加固,知道你正在处理哪些港口。 但是,令人沮丧的是,这只是完整和准确的。 Don t 从未尝试过,但我大概感到羞耻的是,我认为这是想到的。

问题回答

该代码样本是by。 Bruno Reis

class PortScanner {

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

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

public static class ScanResult {
    private int port;

    private boolean isOpen;

    public ScanResult(int port, boolean isOpen) {
        super();
        this.port = port;
        this.isOpen = isOpen;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public boolean isOpen() {
        return isOpen;
    }

    public void setOpen(boolean isOpen) {
        this.isOpen = isOpen;
    }

}
}

除了将扫描相平行外,还可以使用较先进的港口扫描技术(TCP SYN和TCP FIN扫描)在这里解释:。 可在以下网址查阅:

然而,为了使用这些技术,你需要使用原始的TCP/IP的袖珍。 http://www.savarese.com/software/rocksaw/“rel=“nofollow”>RockSaw

我写了我自己的星座港口扫描仪,可以通过TCP-SYN-Scan对港口进行扫描,如Nmap。 它还支持ICMP ping scans,并能够与极高的投稿(取决于网络能够维持什么):

https://github.com/invesdwin/invesdwin-webproxy”rel=“nofollow noreferer”>invesdwin-webproxy

在内部,它使用一个具有约束力的 Javapcap ,并通过JMS/

If you decide to use the Nmap option and want to continue with Java, you should look at Nmap4j on SourceForge.net.

这份简明文稿允许你将Nmap纳入 Java的申请。

纳比,最快的办法是使用动态形成的翻新方法。

Executors.newCachedThreadPool();

这样,它就在采取所有这些行动之前,即当所有这些行动发生时,并且有一项新任务,它将打开新的线索,并预示新的任务。

这里有我的密码snippet(应获得的证书 Jack and Bruno Reis

我也增加了搜索任何IP地址的功能,以便获得某些附加功能和便于使用。

import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

class PortScanner {

    public static void main(final String... args) throws InterruptedException, ExecutionException
    {
        final ExecutorService es = Executors.newCachedThreadPool();
        System.out.print("Please input the IP address you would like to scan for open ports: ");
        Scanner inputScanner = new Scanner(System.in);
        final String ip = inputScanner.nextLine();
        final int timeout = 200;
        final List<Future<ScanResult>> futures = new ArrayList<>();
        for (int port = 1; port <= 65535; port++) {
            //for (int port = 1; port <= 80; port++) {
            futures.add(portIsOpen(es, ip, port, timeout));
        }
        es.awaitTermination(200L, TimeUnit.MILLISECONDS);
        int openPorts = 0;
        for (final Future<ScanResult> f : futures) {
            if (f.get().isOpen()) {
                openPorts++;
                System.out.println(f.get().getPort());
            }
        }
        System.out.println("There are " + openPorts + " open ports on host " + ip + " (probed with a timeout of " +
                           timeout + "ms)");
        es.shutdown();
    }

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

    public static class ScanResult {
        private int port;

        private boolean isOpen;

        public ScanResult(int port, boolean isOpen) {
            super();
            this.port = port;
            this.isOpen = isOpen;
        }

        public int getPort() {
            return port;
        }

        public void setPort(int port) {
            this.port = port;
        }

        public boolean isOpen() {
            return isOpen;
        }

        public void setOpen(boolean isOpen) {
            this.isOpen = isOpen;
        }

    }
}

在大家的激励下,但仅仅这一法典确实奏效!

<>斯特隆>PortScaner

import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class PortScaner {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        final ExecutorService es = Executors.newFixedThreadPool(20);
        final String ip = "127.0.0.1";
        final int timeout = 200;
        final List<Future<ScanResult>> 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<ScanResult> f : futures)
            if (f.get().isOpen()) {
                openPorts++;
                System.out.println(f.get());
            }

        System.out.println("There are " + openPorts + " open ports on host " + ip + " (probed with a timeout of " + timeout + "ms)");
    }


    public static Future<ScanResult> portIsOpen(final ExecutorService es, final String ip, final int port, final int timeout) {
        return es.submit(
            new Callable<ScanResult>() {

                @Override
                public ScanResult call() {
                    try {
                        Socket socket = new Socket();
                        socket.connect(new InetSocketAddress(ip, port), timeout);
                        socket.close();
                        return new ScanResult(port, true);
                } catch (Exception ex) {
                  return  new ScanResult(port, false);
                }

             }
        });
    }
}

class ScanResult

public final class ScanResult {

    private final int port;

    private final boolean isOpen;


    public ScanResult(int port, boolean isOpen) {
        super();
        this.port = port;
        this.isOpen = isOpen;
    }


    /**
     * @return the port
     */
    public int getPort() {
        return port;
    }

    /**
     * @return the isOpen
     */
    public boolean isOpen() {
        return isOpen;
    }


    @Override
    public String toString() {
        return "ScanResult [port=" + port + ", isOpen=" + isOpen + "]";
    }

}

您可以通过使用NIO 2 单一阅读。 通过遵循NIO 2号单行法,我能够扫描所有港口。 请尝试合理的时间说明,并确保你拥有一个大的file descriptor

public static List<HostTarget> getRechabilityStatus(String...hosts, final int port, final int bulkDevicesPingTimeoutinMS) throws Exception {

    List<AsynchronousSocketChannel> channels = new ArrayList<>(hosts.length);
    try {
        List<CompletableFuture<HostTarget>> all = new ArrayList<>(hosts.length);

        List<HostTarget> allHosts = new ArrayList(hosts.length);
        for (String host : hosts) {
            InetSocketAddress address = new InetSocketAddress(host, port);
            HostTarget target = new HostTarget();
            target.setIpAddress(host);
            allHosts.add(target);
            AsynchronousSocketChannel client = AsynchronousSocketChannel.open();
            channels.add(client);
            final CompletableFuture<HostTarget> targetFuture = new CompletableFuture<>();
            all.add(targetFuture);
            client.connect(address, target, new CompletionHandler<Void, HostTarget>() {
                @Override
                public void completed(Void result, HostTarget attachment) {
                    attachment.setIsReachable(true);
                    targetFuture.complete(attachment);
                }

                @Override
                public void failed(Throwable exc, HostTarget attachment) {
                    attachment.setIsReachable(false);
                    attachment.errrorMessage = exc.getMessage();
                    targetFuture.complete(attachment);
                }
            });
        }

        try {
            if(bulkDevicesPingTimeoutinMS > 0) {
                CompletableFuture.allOf(all.toArray(new CompletableFuture[]{})).get(bulkDevicesPingTimeoutinMS, TimeUnit.MILLISECONDS);
            }
            else {
                // Wait for all future to be complete.
                // 1000 scans is taking 7 seconds.
                CompletableFuture.allOf(all.toArray(new CompletableFuture[]{})).join();
            }
        }
        catch (Exception timeoutException) {
            // Ignore
        }
        return allHosts;
    }
    finally {
        for(AsynchronousSocketChannel channel : channels) {
            try {
                channel.close();
            }
            catch (Exception e) {
                if(LOGGER.isDebugEnabled()) {
                    LOGGER.error("Erorr while closing socket", e);
                }
            }
        }
    }

static class HostTarget {

    String ipAddress;
    Boolean isReachable;

    public String getIpAddress() {
        return ipAddress;
    }

    public Boolean getIsReachable() {
        return isReachable;
    }

    public void setIpAddress(String ipAddress) {
        this.ipAddress = ipAddress;
    }
    public void setIsReachable(Boolean isReachable) {
        this.isReachable = isReachable;
    }

}




相关问题
Spring Properties File

Hi have this j2ee web application developed using spring framework. I have a problem with rendering mnessages in nihongo characters from the properties file. I tried converting the file to ascii using ...

Logging a global ID in multiple components

I have a system which contains multiple applications connected together using JMS and Spring Integration. Messages get sent along a chain of applications. [App A] -> [App B] -> [App C] We set a ...

Java Library Size

If I m given two Java Libraries in Jar format, 1 having no bells and whistles, and the other having lots of them that will mostly go unused.... my question is: How will the larger, mostly unused ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

SQLite , Derby vs file system

I m working on a Java desktop application that reads and writes from/to different files. I think a better solution would be to replace the file system by a SQLite database. How hard is it to migrate ...