发现漏洞!Socket编程端口扫描小程序(完整源码)

您所在的位置:网站首页 TCP端口扫描程序 发现漏洞!Socket编程端口扫描小程序(完整源码)

发现漏洞!Socket编程端口扫描小程序(完整源码)

2023-07-25 04:15| 来源: 网络整理| 查看: 265

目录

一、端口扫描技术

二、 单线程建立 Socket 连接

三、 基于 TCP Connect 端口扫描

四、 多线程 TCP 连接扫描

五、 小程序完整源码

一、端口扫描技术

我们都知道,网络中的每台机器都有IP地址,与IP地址密切相关的就是主机的端口,顺便考考你,知道端口号的范围吗?

没错,就是0~65535。在计算机网络中,使用两个字节供16位二进制数来表示端口号。对于这些端口号,一台主机它有开放哪些端口号呢?

比如常见的80,443两个端口号对应的就是HTTP,HTTPS服务,23 端口对应telnet远程管理,25 端口是SMTP服务等等。下面我们就来实现一个简易的端口扫描小程序。

扫描主机开放的端口是常见操作:攻(寻找目的主机开放的端口)与防(检测本机异常开放的端口)。基本的端口扫描可使用的技术:

创建Socket连接:new Socket(ip,port) TCP Connect 探测

本篇适用计算机网络、Java开发、Socket编程以及多线程入门的伙伴!可以结合上一篇《Java开发主机IP扫描神器》,进一步探测网络攻防有用信息!

二、 单线程建立 Socket 连接

现在开始小程序的简易开发流程,从单线程开始一步一步前进。

Socket socket=new Socket(host,port); 复制代码

这里,我们通过创建一个Socket连接,这种方式原理就是与目标IP建立连接,监听端口,如果超过一定时间,说明该端口没有开放,无法成功连接。

无法连接的情况会抛出 IOException 异常,因此,可以在抛出异常的时候判定端口是关闭状态。

具体地实现很简单,我们把扫描端口的操作放到一个线程里面,不影响主程序的运行,然后对给出的端口范围比如 0到100,逐个进行Socket连接,这样就可以知道哪些端口的open的。

try { Socket socket=new Socket(host,port); socket.close(); Platform.runLater(() -> { result.appendText("端口 " +port+ " is open.\n"); }); } catch (IOException e) { result.appendText("端口 " +port+ " is closed.\n"); } 复制代码

这是对我的主机部分端口扫描的结果。

下面是动图可以看一下过程。

三、 基于 TCP Connect 端口扫描

从动态图的扫描过程可以发现,这个速度明显不是人可以容忍的,就像一个网页加载半天一直没显示出来一样,所以,为了更好的用户体验,在此基础上进行优化改进,最重要的就是扫描速度!

上一个方法在遇到端口关闭时等待时间过长,时间成本过高。开始使用另一个方法,基于TCP Connect 的端口扫描。

Socket socket=new Socket(); socket.connect(new InetSocketAddress(host,port),200); socket.close(); 复制代码

这时候,不会对每个ip和端口真正建立连接,而是使用“探测”的方式,通过InetSocketAddress类进行连接,超时时间设定200ms,明显这样速度至少可以提高几倍!

代码实现很简单,这样写就搞定啦

try { Socket socket=new Socket(); socket.connect(new InetSocketAddress(host,port),200); socket.close(); Platform.runLater(() -> { result.appendText("端口 " +port+ " is open.\n"); }); } catch (IOException e) { result.appendText("端口 " +port+ " is closed.\n"); } 复制代码

优化改进之后的对比扫描速度如下动图:

对比之下,扫描速度大幅度提升!

这时,速度的提升是相对而言,比如扫描1000个端口,你就知道有多慢了,还是等不及!

20秒竟然才扫描不到80个端口!粗略计算,1000个端口至少需要4分钟,这是无法接受的!

四、 多线程 TCP 连接扫描

这时候,只能使用后手了,多线程专场…… 嘿嘿

我们现在的小目标就是速度要快,多线程操作真不赖。这里我开启100个线程,来完成这项扫描的任务。

for (int i=0;i{ result.appendText("\n-------------多线程扫描结束-------------\n"); }); } } } 复制代码

再来看看多线程操作的速度有多快,现在感觉很顺畅,1000个端口不到10秒就完成扫描!

是不是感觉挺完美了,但根据常识总是差点什么,其实就是一个进度条显示,就像我们下载东西一样,有个进度条和百分比看着心里有底,安排!

Java中就有可以直接使用的进度类,就是下面这行代码,然后再加到扫描线程里面,实时更新进度。

ProgressBar progressBar=new ProgressBar(); 复制代码

来看看效果,用多线程版本扫描5000个端口。

五、 小程序完整源码

完整源码,毫无保留,建议果断收藏,以免以后使用找不到!

/** * HostScannerFX.java * Copyright (c) 2021 Charzous * All right reserved. * @date 2021-06-07 下午 09:38 */ import javafx.application.Application; import javafx.application.Platform; import javafx.geometry.Insets; import javafx.geometry.Pos; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.layout.BorderPane; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.stage.Stage; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.util.concurrent.atomic.AtomicInteger; public class PortScannerFX extends Application { private TextArea result = new TextArea(); private TextField targetIP = new TextField(); private TextField startPort = new TextField(); private TextField endPort = new TextField(); private Button scan = new Button("扫描"); private Button quickScan = new Button("快速扫描"); private Button threadScan = new Button("多线程扫描"); private Button ex=new Button("退出"); private Button stop=new Button("停止扫描"); private Thread readThread; static AtomicInteger portCount;//用于统计已扫描的端口数量 private ProgressBar progressBar=new ProgressBar(); private Label bar=new Label("0%"); @Override public void start(Stage primaryStage) throws Exception { BorderPane mainPane = new BorderPane(); HBox barBox=new HBox(); barBox.setSpacing(10); barBox.setPadding(new Insets(10, 0, 10, 0)); progressBar.setPrefWidth(700); progressBar.setProgress(0); HBox.setHgrow(progressBar,Priority.ALWAYS); barBox.getChildren().addAll(bar,progressBar); VBox vBox = new VBox(); vBox.setSpacing(10); vBox.setPadding(new Insets(10, 20, 10, 20)); // vBox.setAlignment(Pos.CENTER); VBox.setVgrow(result, Priority.ALWAYS); vBox.getChildren().addAll(new Label("端口扫描结果:"), result,barBox); mainPane.setCenter(vBox); startPort.setPrefWidth(60); endPort.setPrefWidth(60); HBox hBox1 = new HBox(); hBox1.setSpacing(10); hBox1.setPadding(new Insets(10, 20, 10, 20)); hBox1.setAlignment(Pos.CENTER); hBox1.getChildren().addAll(new Label("目标主机ip:"), targetIP, new Label("起始端口号:"), startPort, new Label("结束端口号:"),endPort); HBox hBox2 = new HBox(); hBox2.setSpacing(10); hBox2.setPadding(new Insets(10, 20, 10, 20)); hBox2.setAlignment(Pos.CENTER); hBox2.getChildren().addAll(scan,quickScan,threadScan,stop,ex); VBox vBox1 = new VBox(); vBox1.setSpacing(10); vBox1.setPadding(new Insets(10, 20, 10, 20)); vBox1.setAlignment(Pos.CENTER); vBox1.getChildren().addAll(hBox1, hBox2); mainPane.setBottom(vBox1); Scene scene = new Scene(mainPane, 800, 500); primaryStage.setScene(scene); primaryStage.setTitle("PortScannerFX"); primaryStage.show(); //扫描 scan.setOnAction(event -> { String host = targetIP.getText().trim(); int sp = Integer.parseInt(startPort.getText()); int ep=Integer.parseInt(endPort.getText()); readThread = new Thread(() -> { double num=0.0; for (int i = sp; i { result.appendText("端口 " +port+ " is open.\n"); }); } catch (IOException e) { result.appendText("端口 " +port+ " is closed.\n"); } num++; double finalNum = num; Platform.runLater(()->{ progressBar.setProgress(finalNum/(ep-sp+1));//进度条 bar.setText(""+ Integer.valueOf((int) (finalNum /(ep-sp+1)*100))+"%"); }); } result.appendText("端口扫描结束!\n"); },"scanThread"); readThread.start(); }); //快速扫描 quickScan.setOnAction(event -> { String host = targetIP.getText().trim(); int sp = Integer.parseInt(startPort.getText()); int ep=Integer.parseInt(endPort.getText()); readThread = new Thread(() -> { double num=0; for (int i = sp; i { result.appendText("端口 " +port+ " is open.\n"); }); } catch (IOException e) { result.appendText("端口 " +port+ " is closed.\n"); } num++; double finalNum = num; Platform.runLater(()->{ progressBar.setProgress(finalNum/(ep-sp+1));//进度条 bar.setText(""+ Integer.valueOf((int) (finalNum /(ep-sp+1)*100))+"%"); }); } result.appendText("端口扫描结束!\n"); },"scanThread"); readThread.start(); }); threadScan.setOnAction(event -> { portCount=new AtomicInteger(0); int sp = Integer.parseInt(startPort.getText()); int ep=Integer.parseInt(endPort.getText()); for (int i=0;i { interrupt("scanThread"); }); //退出 ex.setOnAction(event -> { exit(); }); primaryStage.setOnCloseRequest(event -> { exit(); }); } public void interrupt(String threadName){ ThreadGroup currentGroup=Thread.currentThread().getThreadGroup(); int noThreads=currentGroup.activeCount(); Thread[] lstThreads=new Thread[noThreads]; currentGroup.enumerate(lstThreads); for (int i=0;i{ bar.setText(""+ Integer.valueOf((int) ((portCount.doubleValue())/(endP-startP+1)*100))+"%");//进度比 progressBar.setProgress((portCount.doubleValue())/(endP-startP+1));//进度条 }); } if (portCount.get()==(endP-startP+1)){//判断扫描结束 portCount.incrementAndGet(); Platform.runLater(()->{ result.appendText("\n-------------多线程扫描结束-------------\n"); }); } } } public static void main(String[] args) { launch(); } } 复制代码

完整源码,毫无保留,建议果断收藏,以免以后使用找不到,赶紧自己动手开发一个简易端口扫描小程序!

今天用Java开发技术:Socket编程端口扫描小程序,零基础Socket编程详细教程,这篇内容是不是简单、有趣、有收获呢?欢迎交流学习!

最后想跟大家说的是,学习Java必备的知识有哪些呢?很多粉丝私信我Java学习的路线,我推荐了这套知识图谱,粉丝们都觉得质量很不错!

学习Java开发,Socket网络编程等知识,里面有许多有趣的小程序可以做,最近我也在跟着这一套 《Java 工程师学习成长知识图谱》进行体系的学习,是CSDN官方推出的,质量很不错!

其中包含了Java专业体系结构完整详细,推荐给大家学习使用,有兴趣可以扫码查看,最近我也在学习当中,当然,我的文章会记录学习,欢迎大家阅读,比如我的专栏《Socket网络编程》、《Java宝藏》。

展开就是这样的,尺寸870mm*560mm排版好看,内容很充实。推荐给有需要的伙伴,一起来学习Java开发!

**如果觉得不错欢迎“一键三连”哦,点赞收藏关注,评论提问建议,欢迎交流学习!一起加油进步,我们下篇见! 更多详细内容可以到我的CSDN博客查看! **

本篇内容首发我的CSDN博客:csdn-czh.blog.csdn.net/article/det…



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3