Java端口扫描器:如何将连续关闭的端口按范围单行打印?
实现连续关闭端口的范围打印及代码优化
修改后的代码
import java.net.*; public class KalebPortScanner { public static void main(String[] args) { String host = "localhost"; int startingPort = 0; int endingPort = 65535; Integer closedStartPort = null; for (int port = startingPort; port <= endingPort; port++) { boolean isOpen = isPortOpen(host, port, 100); if (isOpen) { // 打印之前连续关闭的端口范围 printClosedPortRange(closedStartPort, port - 1); System.out.println(port + " open"); closedStartPort = null; } else { // 记录连续关闭端口的起始 if (closedStartPort == null) { closedStartPort = port; } } } // 处理扫描结束后仍有连续关闭的端口 printClosedPortRange(closedStartPort, endingPort); } // 单独提取判断端口是否开放的方法,提高可读性 private static boolean isPortOpen(String host, int port, int timeout) { try (Socket socket = new Socket()) { socket.connect(new InetSocketAddress(host, port), timeout); return true; } catch (ConnectException e) { // 连接失败,端口关闭 return false; } catch (Exception e) { // 其他异常,暂时视为端口不可达/关闭 return false; } } // 打印关闭端口的范围或单个端口 private static void printClosedPortRange(Integer start, int end) { if (start == null) { return; } if (start == end) { System.out.println("端口 " + start + " 已关闭"); } else { System.out.println("端口 " + start + " 至 " + end + " 已关闭"); } } }
关键逻辑说明
closedStartPort变量:用来记录连续关闭端口的起始位置,初始为null表示当前没有连续关闭的端口段。- 端口开放时的处理:如果当前端口开放,说明之前的连续关闭端口段结束,调用
printClosedPortRange打印范围,然后重置closedStartPort。 - 端口关闭时的处理:如果是这段关闭端口的第一个,就把当前端口设为起始位置。
- 扫描结束后收尾:循环结束后,可能还有一段未打印的连续关闭端口,需要单独处理。
代码优化建议
- 提取独立方法:把端口检测、范围打印拆成单独方法,让主逻辑更清晰,也方便后续复用和测试。
- 精确异常捕获:不要直接捕获所有
Exception,优先捕获ConnectException(连接失败的核心异常),其他异常按需处理,避免隐藏未知问题。 - 自动资源管理:使用
try-with-resources语法自动关闭Socket,无需手动调用close(),避免资源泄漏。 - 多线程扫描:单线程扫描65535个端口速度极慢,可以用
ExecutorService线程池并发扫描,大幅提升效率(注意控制线程数,避免触发目标主机的防护机制)。 - 参数可配置化:把主机、起始/结束端口、超时时间做成命令行参数或配置项,不用硬编码在代码里。
- 日志替代打印:如果后续需要更规范的输出,可以用日志框架(如SLF4J)替代
System.out.println,便于后续扩展。
内容的提问来源于stack exchange,提问作者Klob
相关产品推荐
相关产品推荐

