当前位置: 首页 > 面试题库 >

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

柯鸿云
2023-03-14
问题内容

我做了一个非常简单的端口扫描程序,但是它运行太慢,因此我正在寻找一种使它扫描速度更快的方法。这是我的代码:

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

此代码测试是否在特定ip上打开了特定端口。对于超时,我使用了最小值,200因为当我降低该值时,它没有足够的时间来测试端口。

它工作正常,但是从0扫描到65535花费的时间太多。还有其他方法可以在不到5分钟的时间内从0扫描到65535吗?


问题答案:

如果您需要为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
}

然后,在第一个代码段中更改BooleanScanResult,然后返回new ScanResult(port, true)new ScanResult(port, false)而不是just truefalse

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



 类似资料:
  • 这一章将会演示如何通过Python的网络连接来开发一个基础的端口扫描器,我们的设计思路是使用socket一遍又一遍的去连接ip与端口的组合的新值,为了方面我们能够快速的完成它,首先需要介绍一点新的概念,for循环: >>> >>> for port in range(1000,1024): ... print "[+] The port is: "+str(port) ... [+] The

  • 本文向大家介绍python端口扫描系统实现方法,包括了python端口扫描系统实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了python端口扫描系统实现方法。分享给大家供大家参考。具体实现方法如下: 该程序的主要功能如下: 1. 从自有API接口获取所有的外网IP段; 2. 用Nmap 遍历扫描所有的IP段,-oX 生成XML的扫描报告; 3. 用xml.etree.Elemen

  • 七、 端口扫描技术 作为一个修车新手,我可能折腾几个小时来摸索怎样把基本工具(锤子,胶带,扳子等) 用于手 头的任务。当我惨痛地失败,把我的老爷车拖到一个真正的技师那儿的时候,他总是在他的工 具箱里翻来翻去,直到拽出一个完美的工具然后似乎不费吹灰之力搞定它。端口扫描的艺术和 这个类似。专家理解成打的扫描技术,选择最适合的一种 (或者组合)来完成给定的任务。 另 一方面,没有经验的用户和刚入门者总是

  • 六、 端口扫描基础 虽然 Nmap 这些年来功能越来越多, 它也是从一个高效的端口扫描器开始的,并且那仍然是它 的核心功能。 nmap target 这个简单的命令扫描主机 target 上的超过 1660 个 TCP 端口。 。 许多传统的端口扫描器只列出所有端口是开放还是关闭的, Nmap 的信息粒度比它们要细得多 它把端口分成六个状态: open(开放的), closed(关闭的),filt

  • 问题 假设我的工作是扫描从直接字节缓冲区读回的所有字节,那么对我来说最快的方法是什么? 我最初问“...利用sun.misc.unsafe”,但这可能是错误的假设。 null 这不同于“我可以使用Unsafe来更快地迭代一个字节[]吗?”问题是,如果没有必要,我甚至不打算在内部将字节拉到byte[]中。 谢谢你抽出时间;只是好奇如果有人(彼得?)做这样的事不安全。

  • 本文向大家介绍用Python编写一个高效的端口扫描器的方法,包括了用Python编写一个高效的端口扫描器的方法的使用技巧和注意事项,需要的朋友参考一下 PyPortScanner python多线程端口扫描器。 输出示例: Github 此端口扫描器的源码,文档及详细调用方法见Github PythonPortScanner by Yaokai。 背景 有时候,在进行网络相关的研究的时候,我们需要