Java端口扫描软件课程设计:Socket并发扫描与Swing界面实现

发布时间:2026/10/9 9:14:39
Java端口扫描软件课程设计:Socket并发扫描与Swing界面实现 简介这是一份面向高校网络安全课程设计场景的Java端口扫描软件完整实现方案适合正在准备课设、需要提交代码与实验报告的学生以及想通过实战理解TCP、ICMP探测原理的Java初学者。资源包共33个文件约267KB以17个class编译文件、3个java源码、6个xml配置、4个txt说明及1份doc实验报告为主另含IDEA工程文件导入后即可运行。软件参照superscan、nmap思路设计支持ping连通性检测、常见端口扫描与操作系统类型识别并通过多线程实现对单个IP、IP段及指定主机名的并发扫描图形界面可实时显示扫描进度、耗时与异常告警。登录账号admin、密码123456配套实验报告便于对照撰写文档。目前已有1157人学习下载可作为课设参考或端口扫描原理练手项目。1. 从课程设计到能跑的工具Java 端口扫描软件到底在做什么很多人对端口扫描的第一印象停留在“黑客工具”四个字上但真正做过网络安全课设的人会知道它更像是一次把网络编程、并发控制和图形界面缝合起来的综合练习。标题里的这套方案核心就是用 Java 写一个带 UI 图形界面的端口扫描软件在 IDEA 里开发调试最后交出一份实验报告。它要解决的问题很具体给定一个 IP 或域名快速判断哪些端口是开放的并把结果直观地展示出来。这件事适合谁一是正在做网络安全课程设计的学生需要一个结构完整、能讲清楚原理又能在答辩时演示的项目二是刚接触 Java 网络编程的开发者想找一个比聊天室更有实战感的练手方向。它不追求工业级扫描器的性能但要求你把 Socket 连接、线程池、Swing 界面这几块真正串起来。下面我按自己踩过坑的顺序把选型、实现、参数和排错讲透。2. 技术选型与扫描原理为什么用 Java 的 Socket 而不是别的2.1 端口扫描的三种常见方式与 Java 的适配度端口扫描从原理上分常见的有 TCP 全连接扫描、TCP SYN 半开扫描和 UDP 扫描。课程设计里最稳妥的是 TCP 全连接扫描因为它直接调用操作系统的 connect 系统调用Java 的Socket类天然支持不需要构造原始数据包也不用管理员权限。SYN 扫描需要自己拼 TCP 报文Java 标准库做不了得依赖第三方库或者本地方法对课设来说复杂度陡增答辩时也容易被追问底层细节。UDP 扫描则因为无连接特性判断端口是否开放非常依赖超时和 ICMP 响应结果不稳定不适合作为主功能。所以我的建议很明确主扫描逻辑用Socket.connect()做全连接探测超时时间设短一点配合线程池并发。这样代码可读、可调试实验报告里也能把三次握手的过程讲清楚。至于 SYN 扫描可以在报告里作为扩展知识提一句但不要写进核心代码。2.2 用 IDEA 建项目与 JDK 版本选择开发环境用 IntelliJ IDEA社区版就够。新建项目时选 Java构建工具用 Maven 或直接普通 Java 项目都行。JDK 版本建议 8 或 11这两个版本在课设环境里兼容性最好Swing 组件也稳定。如果你用的是更高版本注意Socket相关 API 没有破坏性变更但打包成可执行 JAR 时模块化配置会多一步新手容易在这里卡住。创建项目后目录结构大致是PortScanner/ ├── src/ │ └── main/ │ └── java/ │ └── com/scanner/ │ ├── Main.java │ ├── ScannerCore.java │ └── ScannerUI.java └── pom.xmlMain.java只负责启动界面ScannerCore.java放扫描逻辑ScannerUI.java写 Swing 窗口。这样分层的好处是扫描逻辑可以单独用 main 方法测试不用每次都点界面。2.3 单线程扫描为什么必须换成线程池如果用一个 for 循环从 1 扫到 65535每个端口connect超时设 200 毫秒最坏情况下要等 65535 乘以 0.2 秒超过三个半小时。这显然没法演示。实际做法是把端口列表切分交给线程池并发执行。Java 的ExecutorService配合Future或者CompletionService都能做我一般用固定大小线程池线程数控制在 100 到 200 之间。线程数不是越大越好。每个线程发起 connect 都会占用一个本地临时端口和文件描述符线程太多会导致Too many open files或者本地端口耗尽。200 线程在普通笔记本上扫 1000 个端口大约几秒到十几秒具体取决于目标主机的响应速度和网络延迟。实验报告里可以做一个线程数对比表记录不同线程数下的总耗时这比空谈“并发提高效率”有说服力得多。2.4 超时参数怎么定200 毫秒还是 1 秒Socket.connect(new InetSocketAddress(host, port), timeout)里的 timeout 是核心参数。设得太长扫描慢设得太短会把网络延迟导致的正常端口误判为关闭。局域网内目标200 到 500 毫秒足够跨公网扫描建议 1000 毫秒起步。我一般默认给 800 毫秒然后在界面上留一个输入框让用户自己调。这里有个血泪经验connect超时抛出的SocketTimeoutException和连接被拒绝抛出的ConnectException要分开处理。超时说明端口可能被防火墙丢包状态是“过滤”连接被拒绝说明目标主机可达但端口没开状态是“关闭”。很多课设代码把两者都当成“关闭”报告里就少了一个分析维度。3. 核心扫描逻辑的代码实现与参数说明3.1 用 Socket 做单端口探测的最小方法先写一个最基础的方法判断单个端口是否开放import java.net.InetSocketAddress; import java.net.Socket; public class ScannerCore { /** * 探测单个端口是否开放 * param host 目标主机 IP 或域名 * param port 目标端口范围 1-65535 * param timeout 连接超时毫秒数 * return true 表示端口开放false 表示关闭或超时 */ public static boolean isPortOpen(String host, int port, int timeout) { try (Socket socket new Socket()) { // connect 方法会阻塞直到成功或超时 socket.connect(new InetSocketAddress(host, port), timeout); return true; } catch (Exception e) { // 连接被拒绝、超时、主机不可达都走这里 return false; } } }这段代码用 try-with-resources 确保 Socket 用完自动关闭避免文件描述符泄漏。InetSocketAddress会先做域名解析如果传入的是域名解析失败也会抛异常被 catch 捕获。参数timeout直接决定扫描速度建议在调用处从界面读取。3.2 线程池并发扫描与结果收集单端口方法有了接下来把它塞进线程池。下面是一个可复用的并发扫描方法import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; public class ScannerCore { /** * 并发扫描多个端口 * param host 目标主机 * param ports 待扫描端口列表 * param timeout 单端口超时毫秒 * param threadCount 线程池大小 * return 开放的端口列表 */ public static ListInteger scanPorts(String host, ListInteger ports, int timeout, int threadCount) { ExecutorService pool Executors.newFixedThreadPool(threadCount); ListFutureInteger futures new ArrayList(); for (int port : ports) { FutureInteger future pool.submit(() - { if (isPortOpen(host, port, timeout)) { return port; } return -1; }); futures.add(future); } ListInteger openPorts new ArrayList(); for (FutureInteger future : futures) { try { // 获取每个任务的返回值超时时间给足 int result future.get(timeout 500, TimeUnit.MILLISECONDS); if (result ! -1) { openPorts.add(result); } } catch (Exception e) { // 单个任务异常不影响整体 } } pool.shutdown(); return openPorts; } }这里用Future收集结果future.get的超时比 connect 超时多 500 毫秒防止任务还没跑完就被取消。线程池大小threadCount从界面传入默认 150。注意pool.shutdown()放在最后不要用shutdownNow否则可能中断正在进行的连接。3.3 端口范围解析与常见端口预设界面上一般让用户输入“1-1000”或者“22,80,443”这种格式。解析逻辑要单独写避免把非法输入传给扫描核心import java.util.ArrayList; import java.util.List; public class PortParser { /** * 解析端口表达式支持 1-1000 和 22,80,443 两种格式 * param expression 用户输入 * return 端口列表 */ public static ListInteger parse(String expression) { ListInteger ports new ArrayList(); if (expression null || expression.trim().isEmpty()) { return ports; } String[] parts expression.split(,); for (String part : parts) { part part.trim(); if (part.contains(-)) { String[] range part.split(-); int start Integer.parseInt(range[0].trim()); int end Integer.parseInt(range[1].trim()); for (int i start; i end; i) { if (i 1 i 65535) { ports.add(i); } } } else { int port Integer.parseInt(part); if (port 1 port 65535) { ports.add(port); } } } return ports; } }参数校验不能省。用户输入“0-70000”时超出范围的端口要过滤掉否则InetSocketAddress会抛IllegalArgumentException。常见端口预设可以在界面上放一个下拉框比如“常用端口”对应 21,22,23,25,53,80,110,135,139,143,443,445,1433,1521,3306,3389,8080方便快速演示。3.4 扫描结果的状态区分与输出格式前面提到超时和拒绝要分开。改进isPortOpen让它返回状态枚举而不是布尔值public enum PortStatus { OPEN, CLOSED, FILTERED } public static PortStatus checkPort(String host, int port, int timeout) { try (Socket socket new Socket()) { socket.connect(new InetSocketAddress(host, port), timeout); return PortStatus.OPEN; } catch (java.net.SocketTimeoutException e) { return PortStatus.FILTERED; } catch (java.net.ConnectException e) { return PortStatus.CLOSED; } catch (Exception e) { return PortStatus.FILTERED; } }这样界面上可以显示三种颜色绿色开放、红色关闭、灰色过滤。实验报告里也能画出状态分布饼图比单纯列开放端口更有分析价值。输出格式建议用表格每行显示端口号、服务名可选、状态、耗时。服务名可以内置一个简单映射比如 80 对应 HTTP443 对应 HTTPS3306 对应 MySQL。4. Swing 图形界面把扫描结果实时显示出来4.1 界面布局与关键组件Swing 虽然老但课设够用而且 IDEA 自带窗体设计器拖拽就能生成代码。主界面我一般分三块顶部输入区、中间结果表格、底部按钮和进度条。输入区放目标 IP 输入框、端口范围输入框、超时输入框、线程数输入框。结果表格用JTable模型用DefaultTableModel列名是“端口”“状态”“耗时(ms)”。关键组件组件类型作用hostFieldJTextField输入目标 IP 或域名portFieldJTextField输入端口表达式timeoutFieldJTextField输入超时毫秒threadFieldJTextField输入线程数startButtonJButton开始扫描resultTableJTable显示扫描结果progressBarJProgressBar显示扫描进度布局用BorderLayout加GridBagLayout组合不要用绝对定位否则换个分辨率就错位。4.2 扫描线程与 EDT 的交互为什么界面会卡死Swing 是单线程模型所有界面更新必须在事件调度线程EDT里做。如果你在按钮的actionPerformed里直接调用scanPorts整个界面会卡住直到扫描结束进度条也不动。正确做法是把扫描任务放到一个单独的SwingWorker里在doInBackground中执行扫描在process或done中更新表格。import javax.swing.*; import java.util.List; public class ScanWorker extends SwingWorkerVoid, Object[] { private final String host; private final ListInteger ports; private final int timeout; private final int threadCount; private final DefaultTableModel model; public ScanWorker(String host, ListInteger ports, int timeout, int threadCount, DefaultTableModel model) { this.host host; this.ports ports; this.timeout timeout; this.threadCount threadCount; this.model model; } Override protected Void doInBackground() throws Exception { // 分批扫描每批完成后 publish 结果 int batchSize 50; for (int i 0; i ports.size(); i batchSize) { ListInteger batch ports.subList(i, Math.min(i batchSize, ports.size())); for (int port : batch) { long start System.currentTimeMillis(); PortStatus status ScannerCore.checkPort(host, port, timeout); long cost System.currentTimeMillis() - start; publish(new Object[]{port, status, cost}); } } return null; } Override protected void process(ListObject[] chunks) { for (Object[] row : chunks) { model.addRow(row); } } }publish和process是 SwingWorker 提供的线程安全通信方式process自动在 EDT 里执行。这样界面不会卡进度条也能通过setProgress更新。注意doInBackground里不要碰任何 Swing 组件否则就是玄学崩溃。4.3 进度条与取消功能的实现进度条用JProgressBar范围设 0 到端口总数每完成一个端口setValue加一。取消按钮调用worker.cancel(true)然后在doInBackground的循环里检查isCancelled()如果为 true 就提前返回。取消后记得把线程池关掉否则后台线程还在跑程序退不出去。if (isCancelled()) { pool.shutdownNow(); return null; }这段要放在批次循环的开头。shutdownNow会尝试中断正在 connect 的线程但 Socket.connect 不响应中断所以实际取消可能有延迟这是正常现象报告里可以说明。4.4 结果导出与实验报告数据来源扫描完成后把JTable里的数据导出成 CSV 或 TXT方便贴进实验报告。用BufferedWriter写文件每行格式“端口,状态,耗时”。导出按钮的监听器里遍历model.getRowCount()和getColumnCount()注意处理文件写入异常。实验报告里需要的数据通常包括测试目标、端口范围、线程数、超时、开放端口列表、总耗时、不同线程数对比。这些都可以从界面和日志里拿到。建议在扫描开始时记录System.currentTimeMillis()结束时再记一次差值就是总耗时。5. 避坑与排查课设里最容易翻车的五个地方5.1 现象扫描 localhost 全部端口都显示关闭原因很多系统对 localhost 的未监听端口会立即返回 RSTConnectException被捕获后返回 CLOSED这是正常的。但如果你扫的是本机而本机防火墙拦截了 connect 请求可能返回超时状态变成 FILTERED。解决换一个已知开放端口测试比如本机开了 8080 就扫 8080确认逻辑正确后再扫其他目标。5.2 现象程序跑一会儿报 Too many open files原因线程数设得太大或者 Socket 没有及时关闭。虽然 try-with-resources 会关但如果线程池队列里积压了大量任务每个任务都持有一个 Socket文件描述符就会耗尽。解决线程数降到 100 到 200并且在isPortOpen里确保异常路径也能关闭 Socket。Linux 下可以用ulimit -n查看上限Windows 下一般不会遇到这个问题。5.3 现象界面点击开始后无响应进度条不动原因扫描代码写在了 EDT 里或者SwingWorker的process没有被正确触发。解决确认扫描逻辑在doInBackground中publish在循环里被调用。如果还是不动检查process方法有没有加Override方法名拼写是否正确。这个坑我踩过少写一个Override导致父类方法没被覆盖结果就是黑匣子啥也不显示。5.4 现象域名解析失败导致整个扫描中断原因InetSocketAddress构造时如果域名解析不了会抛UnknownHostException这个异常在checkPort里被 catch 了但如果你在解析端口列表之前就解析域名可能直接崩掉。解决把域名解析放在扫描开始前单独做一次解析失败就弹窗提示不要进入扫描流程。或者用InetAddress.getByName(host)先验证。5.5 现象IDEA 里运行正常打包成 JAR 后界面乱码或打不开原因Swing 默认字体在打包后可能找不到或者MANIFEST.MF没指定主类。解决打包时用 Maven 的maven-jar-plugin配置mainClass字体统一用UIManager.setLookAndFeel设置系统外观。如果中文乱码在启动参数加-Dfile.encodingUTF-8。这个坑在交作业前一定要测一遍别等到答辩现场才翻车。6. 进阶技巧让课设从及格变成优秀如果你想让这个端口扫描软件在课设里拿高分光能跑还不够得在细节上做出差异。第一个技巧是加一个“服务识别”功能对开放的端口尝试读取 banner。比如连上 80 端口后发一个HEAD / HTTP/1.0请求读几行响应就能判断是不是 HTTP 服务。代码不复杂在checkPort返回 OPEN 之后再开一个 Socket 读 1024 字节超时设 500 毫秒。注意有些服务不主动发 banner读不到就返回“未知”不要死等。第二个技巧是扫描结果的可视化。除了表格可以加一个简单的柱状图用JFreeChart或者自己用Graphics2D画。横轴是端口号纵轴是耗时开放的端口用绿色柱子标出来。这样答辩时演示效果很好报告里也能放图。如果不想引入第三方库用JPanel重写paintComponent根据结果列表画矩形就行。第三个技巧是加一个“扫描历史”功能把每次扫描的目标、时间、开放端口存到本地 SQLite 或者干脆写 JSON 文件。下次打开软件能加载历史记录对比两次扫描的差异。这个功能在报告里可以写成“资产变化监控”的雏形听起来就比单纯扫描器高级。验证方法上我一般用三个目标做测试本机 localhost 验证基本逻辑一台已知开放 22 和 80 的局域网机器验证准确性一个不存在的 IP 验证超时处理。每次改完参数都跑一遍这三个用例确保没有回归。参数调优时重点看线程数和超时的组合记录不同组合下的总耗时和误报率选一个平衡点写进报告。最后说个习惯我每次写完扫描核心都会先用一个main方法直接调用scanPorts打印结果确认逻辑没问题再接界面。这样能把网络问题和界面问题分开排查省下大量后悔药。希望帮到你。本文还有配套的精品资源点击获取

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询