栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用Java扫描端口的最快方法

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Java扫描端口的最快方法

如果您需要为65536个端口中的每个端口花费200毫秒的时间(在最坏的情况下,防火墙会阻止所有内容,从而使每个端口都超时),那么计算就非常简单:您需要13,000秒,或者大约3个小时,一半。

您有2个(非专有)选项可以使其更快:

  • 减少您的超时
  • 并行化您的代码

由于操作是受I / O约束的(与CPU约束相反,也就是说,您花时间等待I / O,而不是花一些时间完成大量计算),因此 可以使用很多线程
。尝试从20开始。它们会将其中的3小时半分开, 因此最长预期时间约为10分钟
。只需记住,这将给另一侧带来压力,即,被扫描的主机将看到具有“不合理”或“奇怪”模式的大量网络活动,从而使扫描非常容易检测。

最简单的方法(即更改最少)是使用ExecutorService和Future API:

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

如果您需要知道 打开了哪些端口 (而不是如上例中那样 打开 了多少 端口
),则需要将函数的返回类型更改为

Future<SomethingElse>
,其中
SomethingElse
将保留端口和扫描结果,其中包括喜欢:

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

然后,在第一个代码段中更改

Boolean
ScanResult
,然后返回
new ScanResult(port, true)
newScanResult(port, false)
而不是just
true
false

编辑:实际上,我只是注意到:在这种特殊情况下,您不需要ScanResult类来保存结果+端口,并且仍然知道哪个端口是打开的。既然你添加期货一个 列表
,这是 有序的 ,并且,以后,你 处理它们在您添加它们的顺序相同
,你可以有一个计数器,你会在每次迭代增量知道你正在处理哪个端口。但是,嘿,这只是为了完整和精确。 永远不要尝试这样做
,这太可怕了,我为自己想到的事情感到mostly愧… 使用ScanResult对象更加简洁
,代码更易于阅读和维护,并允许您以后使用,例如,使用a

CompletionService
改进扫描仪。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/486575.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号