如果你需要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 从未尝试过,但我大概感到羞耻的是,我认为这是想到的。