java多线程实现端口扫描,使用Java开发多线程端口扫描工具
前言:这里只给出命令行版的扫描工具,后续可能是写一个独立的界面,或者是集成到其他工具上去。
一 扫描原理
其实原理非常简单,就是使用Socket去连接目标IP或者域名的指定端口,如果能够连上则说明该端口是打开的。反之,要是在连接超时之前都没有连上,则将该端口判断为关闭状态。下面我将分别说明两种基本的扫描方式:(1)扫描一个连续的端口段;(2)仅扫描一个指定的端口集合
二 使用多线程扫描目标主机一个段的端口开放情况
/**
* 多线程扫描目标主机一个段的端口开放情况
*
* @param ip
* 待扫描IP或域名,eg:180.97.161.184 www.zifangsky.cn
* @param startPort
* 起始端口
* @param endPort
* 结束端口
* @param threadNumber
* 线程数
* @param timeout
* 连接超时时间
* */
public void scanLargePorts(String ip, int startPort, int endPort,
int threadNumber, int timeout) {
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 0; i < threadNumber; i++) {
ScanMethod1 scanMethod1 = new ScanMethod1(ip, startPort, endPort,
threadNumber, i, timeout);
threadPool.execute(scanMethod1);
}
threadPool.shutdown();
// 每秒中查看一次是否已经扫描结束
while (true) {
if (threadPool.isTerminated()) {
System.out.println("扫描结束");
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36/**
* 多线程扫描目标主机一个段的端口开放情况
*
* @param ip
* 待扫描IP或域名,eg:180.97.161.184 www.zifangsky.cn
* @param startPort
* 起始端口
* @param endPort
* 结束端口
* @param threadNumber
* 线程数
* @param timeout
* 连接超时时间
* */
publicvoidscanLargePorts(Stringip,intstartPort,intendPort,
intthreadNumber,inttimeout){
ExecutorServicethreadPool=Executors.newCachedThreadPool();
for(inti=0;i
ScanMethod1scanMethod1=newScanMethod1(ip,startPort,endPort,
threadNumber,i,timeout);
threadPool.execute(scanMethod1);
}
threadPool.shutdown();
// 每秒中查看一次是否已经扫描结束
while(true){
if(threadPool.isTerminated()){
System.out.println("扫描结束");
break;
}
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
然后是一个内部类ScanMethod1实现了Runnable接口:
/**
* 扫描方式一:针对起始结束端口,进行逐个扫描
*
* */
class ScanMethod1 implements Runnable {
private String ip; // 目标IP
private int startPort, endPort, threadNumber, serial, timeout; // 起始和结束端口,线程数,这是第几个线程,超时时间
/**
* 初始化
*
* @param ip
* 待扫描IP或域名
* @param startPort
* 起始端口
* @param endPort
* 结束端口
* @param threadNumber
* 线程数
* @param serial
* 标记是第几个线程
* @param timeout
* 连接超时时间
* */
public ScanMethod1(String ip, int startPort, int endPort,
int threadNumber, int serial, int timeout) {
this.ip = ip;
this.startPort = startPort;
this.endPort = endPort;
this.threadNumber = threadNumber;
this.serial = serial;
this.timeout = timeout;
}
public void run() {
int port = 0;
try {
InetAddress address = InetAddress.getByName(ip);
Socket socket;
SocketAddress socketAddress;
for (port = startPort + serial; port <= endPort; port += threadNumber) {
socket = new Socket();
socketAddress = new InetSocketAddress(address, port);
try {
socket.connect(socketAddress, timeout); // 超时时间
socket.close();
System.out.println("端口 " + port + " :开放");
} catch (IOException e) {
// System.out.println("端口 " + port + " :关闭");
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57/**
* 扫描方式一:针对起始结束端口,进行逐个扫描
*
* */
classScanMethod1implementsRunnable{
privateStringip;// 目标IP
privateintstartPort,endPort,threadNumber,serial,timeout;// 起始和结束端口,线程数,这是第几个线程,超时时间
/**
* 初始化
*
* @param ip
* 待扫描IP或域名
* @param startPort
* 起始端口
* @param endPort
* 结束端口
* @param threadNumber
* 线程数
* @param serial
* 标记是第几个线程
* @param timeout
* 连接超时时间
* */
publicScanMethod1(Stringip,intstartPort,intendPort,
intthreadNumber,intserial,inttimeout){
this.ip=ip;
this.startPort=startPort;
this.endPort=endPort;
this.threadNumber=threadNumber;
this.serial=serial;
this.timeout=timeout;
}
publicvoidrun(){
intport=0;
try{
InetAddressaddress=InetAddress.getByName(ip);
Socketsocket;
SocketAddresssocketAddress;
for(port=startPort+serial;port<=endPort;port+=threadNumber){
socket=newSocket();
socketAddress=newInetSocketAddress(address,port);
try{
socket.connect(socketAddress,timeout);// 超时时间
socket.close();
System.out.println("端口 "+port+" :开放");
}catch(IOExceptione){
// System.out.println("端口 " + port + " :关闭");
}
}
}catch(UnknownHostExceptione){
e.printStackTrace();
}
}
}
三 使用多线程扫描目标主机指定Set端口集合的开放情况
/**
* 多线程扫描目标主机指定Set端口集合的开放情况
*
* @param ip
* 待扫描IP或域名,eg:180.97.161.184 www.zifangsky.cn
* @param portSet
* 待扫描的端口的Set集合
* @param threadNumber
* 线程数
* @param timeout
* 连接超时时间
* */
public void scanLargePorts(String ip, Set portSet,
int threadNumber, int timeout) {
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 0; i < threadNumber; i++) {
ScanMethod2 scanMethod2 = new ScanMethod2(ip, portSet,
threadNumber, i, timeout);
threadPool.execute(scanMethod2);
}
threadPool.shutdown();
while (true) {
if (threadPool.isTerminated()) {
System.out.println("扫描结束");
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33/**
* 多线程扫描目标主机指定Set端口集合的开放情况
*
* @param ip
* 待扫描IP或域名,eg:180.97.161.184 www.zifangsky.cn
* @param portSet
* 待扫描的端口的Set集合
* @param threadNumber
* 线程数
* @param timeout
* 连接超时时间
* */
publicvoidscanLargePorts(Stringip,SetportSet,
intthreadNumber,inttimeout){
ExecutorServicethreadPool=Executors.newCachedThreadPool();
for(inti=0;i
ScanMethod2scanMethod2=newScanMethod2(ip,portSet,
threadNumber,i,timeout);
threadPool.execute(scanMethod2);
}
threadPool.shutdown();
while(true){
if(threadPool.isTerminated()){
System.out.println("扫描结束");
break;
}
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
e.printStackTrace();
}
}
}
具体的线程内部类跟上面类似,代码如下:
/**
* 扫描方式二:针对一个待扫描的端口的Set集合进行扫描
*
* */
private class ScanMethod2 implements Runnable {
private String ip; // 目标IP
private Set portSet; // 待扫描的端口的Set集合
private int threadNumber, serial, timeout; // 线程数,这是第几个线程,超时时间
public ScanMethod2(String ip, Set portSet, int threadNumber,
int serial, int timeout) {
this.ip = ip;
this.portSet = portSet;
this.threadNumber = threadNumber;
this.serial = serial;
this.timeout = timeout;
}
public void run() {
int port = 0;
Integer[] ports = portSet.toArray(new Integer[portSet.size()]); // Set转数组
try {
InetAddress address = InetAddress.getByName(ip);
Socket socket;
SocketAddress socketAddress;
if (ports.length < 1)
return;
for (port = 0 + serial; port <= ports.length - 1; port += threadNumber) {
socket = new Socket();
socketAddress = new InetSocketAddress(address, ports[port]);
try {
socket.connect(socketAddress, timeout);
socket.close();
System.out.println("端口 " + ports[port] + " :开放");
} catch (IOException e) {
// System.out.println("端口 " + ports[port] + " :关闭");
}
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45/**
* 扫描方式二:针对一个待扫描的端口的Set集合进行扫描
*
* */
privateclassScanMethod2implementsRunnable{
privateStringip;// 目标IP
privateSetportSet;// 待扫描的端口的Set集合
privateintthreadNumber,serial,timeout;// 线程数,这是第几个线程,超时时间
publicScanMethod2(Stringip,SetportSet,intthreadNumber,
intserial,inttimeout){
this.ip=ip;
this.portSet=portSet;
this.threadNumber=threadNumber;
this.serial=serial;
this.timeout=timeout;
}
publicvoidrun(){
intport=0;
Integer[]ports=portSet.toArray(newInteger[portSet.size()]);// Set转数组
try{
InetAddressaddress=InetAddress.getByName(ip);
Socketsocket;
SocketAddresssocketAddress;
if(ports.length<1)
return;
for(port=0+serial;port<=ports.length-1;port+=threadNumber){
socket=newSocket();
socketAddress=newInetSocketAddress(address,ports[port]);
try{
socket.connect(socketAddress,timeout);
socket.close();
System.out.println("端口 "+ports[port]+" :开放");
}catch(IOExceptione){
// System.out.println("端口 " + ports[port] + " :关闭");
}
}
}catch(UnknownHostExceptione){
e.printStackTrace();
}
}
}
四两种扫描方式的测试用例
public static void main(String[] args) {
PortScanDemo portScanDemo = new PortScanDemo();
//方式1
// portScanDemo.scanLargePorts("ultra-book.co", 20, 10000, 5,800);
// portScanDemo.scanLargePorts("180.97.161.184", 1, 100, 5);
//方式2
Set portSet = new LinkedHashSet();
Integer[] ports = new Integer[] { 21, 22, 23, 25, 26, 69, 80, 110, 143,
443, 465, 995, 1080, 1158, 1433, 1521, 2100, 3128, 3306, 3389,
7001, 8080, 8081, 9080, 9090,43958};
portSet.addAll(Arrays.asList(ports));
portScanDemo.scanLargePorts("ultra-book.co", portSet, 5, 800);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15publicstaticvoidmain(String[]args){
PortScanDemoportScanDemo=newPortScanDemo();
//方式1
// portScanDemo.scanLargePorts("ultra-book.co", 20, 10000, 5,800);
// portScanDemo.scanLargePorts("180.97.161.184", 1, 100, 5);
//方式2
SetportSet=newLinkedHashSet();
Integer[]ports=newInteger[]{21,22,23,25,26,69,80,110,143,
443,465,995,1080,1158,1433,1521,2100,3128,3306,3389,
7001,8080,8081,9080,9090,43958};
portSet.addAll(Arrays.asList(ports));
portScanDemo.scanLargePorts("ultra-book.co",portSet,5,800);
}
五测试结果
注:1 超时时间是以毫秒为单位,其中要是扫描国内的IP可以把这个时间适当设置低一点,200~500左右。相反,要是扫描国外IP就需要把这个时间适当设置大一点,不然有可能把本来打开的端口也漏掉了
java多线程实现端口扫描,使用Java开发多线程端口扫描工具相关推荐
- java环境搭好 软件无法运城_Javaweb开发环境搭建常用工具类型
随着互联网的不断发展,无论是前端开发还是后端开发都越发垂直细分化,而今天我们就通过案例分析来了解一下,Javaweb开发环境搭建常用工具类型. 一:Web相关概念 Web程序也就是一般所说的网站,由服 ...
- java ee web pdf_Java EE Web高级开发案例 PDF扫描版[69MB]
Java EE Web高级开发案例 内容简介: <Java EE Web高级开发案例>充分体现了高等职业教育的特点,突出了理论和实践的紧密结合,以充分掌握基本技术技能和必要的基本知识为出发 ...
- 今天用Java开发主机IP扫描神器,零基础Socket编程详细
目录 一.开发背景 二.准备工作 三.远程主机 IP 探测 四.核心算法 1.IP地址转化为十进制数 2.十进制数转化为IP地址 五.主机 IP 扫描神器界面 六.各功能代码及IP扫描演示 1.主机扫 ...
- Java语言与系统设计笔记(II:从多线程开发到网络编程)
ch6.Java多线程开发 6.1 进程与线程的概念 进程(Process):操作系统中能够"同时"运行的多个应用程序(QQ.浏览器.Word.WPS). 线程(Thread):一 ...
- 【资料】翘首期盼247天!《阿里巴巴Java开发手册》扫描插件详情介绍
引言:自从2月9日<阿里巴巴Java开发手册>面向业界公布以来,大家一直期待着静态化扫描工具的问世,在<手册>终极版发布时,我们曾经承诺将在2017杭州云栖大会上进行规约插件的 ...
- android xml java混合编程_Java学习中注解与多线程,网络编程与XML技术
本部分内容主要有集合框架及泛型,实用类,输入和输出处理,注解与多线程,网络编程与XML技术.初次学习这部分会感觉很难,主要是概念难于理解,最好是多看看例子,多练习.下面是个人的总结 拉勾IT课小编为大 ...
- 大华SDK+JAVA+4g网络摄像头进行二次开发
前言 监控,相信大家都不陌生.现在的监控技术发展迅速,国内以海康威视为首的智能视频监控提供商也层出不穷.现在,这些提供商都已经提供了相应的SDK以及API接口,能够很好的支撑我们进行摄像机的二次开发工 ...
- Java后台微信点餐小程序开发最新版笔记,Springboot+Mysql+Freemarker+Bootstrap+微信小程序实现扫码点餐小程序,包含语音提示,微信消息推送,网页管理后台
由于之前的Java后台微信点餐小程序有些知识点过时了,所以今天重新出一版,把里面过时的知识点更新下 前五章是部署笔记,后面是知识点的详细讲解,大家可以先看部署笔记,部署起来后,再跟着详细知识学习. 第 ...
- Java基础巩固(二)异常,多线程,线程池,IO流,Properties集合,IO工具类,字符流,对象流,Stream,Lambda表达式
一.异常,多线程 学习目标 : 异常的概述 异常的分类 异常的处理方式 自定义异常 多线程入门 1 异常的概述 1.1 什么是异常? 异常就是程序出现了不正常情况 , 程序在执行过程中 , 数据导致程 ...
最新文章
- Redis的Pub/Sub模式
- (王道408考研操作系统)第二章进程管理-第四节1:死锁相关概念
- Android布局_LinearLayout布局
- 我的世界服务器显示玩家坐标,我的世界手游版怎么显示玩家坐标
- 设计灵感|美容护肤主题,图文排版在Banner中的正确打开位置!
- C语言线性表怎么输入字符串,用c语言创建一个线性表输入元素求直接后继
- 苹果Mac高级音乐播放器:Swinsian
- 命令行安装DHCP服务器
- 【C语言数据结构7】--串的实现
- DZ论坛php代码,Discuz!代码大全 - Discuz!-安装使用 - Discuz! 官方站 - Powered by Discuz!...
- html网页音乐手机播放,网页添加背景音乐代码,支持手机端的html5代码播放器
- 模拟游戏--艾伦·图灵的传奇人生
- 注册github账号详细中文版教程【精选】
- 努比亚NX549 miniS 刷机遇坑记录,最终完美解决方案
- vba删除word中图片与文本框等shape
- Laravel5.8调试消息队列RabbitMQ
- 数字电路中的时钟(2) PPM 计算
- python网课 知乎_如何看待风变编程的 Python 网课
- 微信小程序前台开发——实现登录,底部导航栏,顶部导航栏(分类显示)
- CookGAN Causality based Text-to-Image Synthesis
热门文章
- 2020-WEB开发路线图,和即将到来的 2021-WEB技术清单
- Java 源码中 unchecked 什么意思
- windows下 网络命令(待续)
- 安装kube-prometheus项目:k8s部署prometheus、监控k8s核心组件、添加告警(微信、钉钉、企业微信)、进行数据持久化
- AtomicLong与LongAdder执行效率对比
- idea 添加jar包到maven项目的方法
- RedisTemplate操作hash数据类型示例
- MongoRepository findById方法使用示例
- Vue调用后端接口http ajax请求组件封装及proxyTable跨域问题解决超详细案例
- 【爬蟲】爬蟲概述、分類及運行原理