软件编程
位置:首页>> 软件编程>> java编程>> Java网络编程实现的简单端口扫描器示例

Java网络编程实现的简单端口扫描器示例

作者:wangbowj123  发布时间:2022-04-17 09:59:18 

标签:Java,网络编程,端口扫描器

本文实例讲述了Java网络编程实现的简单端口扫描器。分享给大家供大家参考,具体如下:

在计算机网络的学习中,不由得觉得这门课的零碎知识点异常之多,同时因为学习的课本是老外的教材——自顶向下方法,因此学习起来不免觉得吃力,但是从老外的教材里更能从一定高度理解计算机网络的知识体系,也是乐在其中,同时做英语的习题感觉也很有趣味,从各方面来说可以说是获益良多,认识了很多专业词汇。节课之后,便想做一个简单的端口扫描器,用的语言是java,因为实现界面很简单,同时也有封装好的Socket类可以使用,主要思路如下:

在主程序界面里输入指定主机名或ip地址,按下start按钮,就可以扫描主机的常用端口是否打开。内部设置了常用端口号: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。也可以自行修改。程序实现原理就是利用Java建立Socket去连接目标ip的指定端口,如果能连接上就证明该端口开放。反之,若在超时之前都没有连接上,则该端口是关闭的,同时会产生异常。同时考虑到单线程操作效率较低,也利用了Java可以多线程编程的特点,使用了多线程扫描目标主机的一个端口是否开放,因此最终显示结果中端口的排列顺序是随机的,且内部设定最多同时运行10个线程(可以根据实际情况更改)。

主要运用的网络知识就是套接字的使用。以及java内部的List容器,java的界面设计,界面布局,以及简单的泛型编程的用法。

主要代码如下:


import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ScanPort extends JFrame {
/**
 * 端口扫描启动主程序
 */
private static final long serialVersionUID = 1L;
String str1 = " 常见端口有:";
String str2 = "ftp:21,22,telnet:23,smtp:25,http:80";
String str3 = "dns:53,tftp:69,snmp:161,162";
String str4 = "1158,1433,1521,2100,3128,26,69";
String str5 = "3306,3389,7001,8080,8081,110,143";
String str6 = "9080,9090,43958,443,465,995,1080";
JButton jb1 = new JButton("strat");
JTextArea jta = new JTextArea();
JScrollPane jsp = new JScrollPane(jta);
JTextField jtf = new JTextField(17);
String IP = "";//待扫描IP或域名
List <Integer>portList = new LinkedList<Integer>();// 定义一个List容器表示扫描的团口的List集合
Integer[] ports = new Integer[] { 21, 22, 23, 25, 26, 53,69, 80, 110, 143,
  443,465,69,161,162,135,995,1080,1158,1433,1521,2100, 3128, 3306, 3389,
  7001, 8080, 8081, 9080, 9090, 43958 ,135,445,1025,1026,1027,1028,1055,5357};
// 常见端口集合
public ScanPort() {
 this.add(getPanel(), BorderLayout.SOUTH);
 jsp.setBorder(BorderFactory.createEtchedBorder());
 jsp.setBackground(Color.cyan);
 this.add(jsp, BorderLayout.CENTER);
 this.add(getPanel2(), BorderLayout.NORTH);
 this.add(getPanel3(), BorderLayout.WEST);
 this.setBounds(300, 60, 600, 600);
 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 this.setTitle("ScanPort");
 jta.setTabSize(4);
 jta.setFont(new Font("标楷体", Font.BOLD, 16));
 jta.setLineWrap(true);// 激活自动换行功能
 jta.setWrapStyleWord(true);// 激活断行不断字功能
 portList.addAll(Arrays.asList(ports));
 //将ports中的值加入到set中,并去掉重复的
 jb1.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
   // TODO Auto-generated method stub
   IP = jta.getText();
   //ip为文本框内输入的字符串
   scanPorts(IP, portList, 10, 800);
   //超时时间设定为800,线程数设定为10
  }
 });
 this.setVisible(true);
}
/**
 * 多线程扫描目标主机指定List端口集合的开放情况
 *
 * @param ip
 *   待扫描IP或域名
 * @param portList
 *   待扫描的端口的List集合
 * @param threadNumber
 *   线程数
 * @param timeout
 *   连接超时时间
 * */
public void scanPorts(String ip, List<Integer> portSet,int threadNumber, int timeout) {
 ExecutorService threadPool = Executors.newCachedThreadPool();
 //线程池
 for (int i = 0; i < threadNumber; i++) {
  //10个线程 加入到线程池里
  ScanMethod scanMethod2 = new ScanMethod(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();
  }
 }// end of while
}
/*
 * 扫描方式:针对一个待扫描的端口的List集合进行扫描
 */
private class ScanMethod implements Runnable {
 private String ip; // 目标IP
 private List<Integer> portList; // 待扫描的端口的List集合
 private int threadNumber, serial, timeout; // 线程数,这是第几个线程,超时时间
 public ScanMethod(String ip, List<Integer> portList, int threadNumber,int serial, int timeout) {
  this.ip = ip;
  this.portList = portList;
  this.threadNumber = threadNumber;
  this.serial = serial;
  this.timeout = timeout;
 }
 public void run() {
  int port = 0;
  Integer[] ports = portList.toArray(new Integer[portList.size()]); // List转数组
  try {
   InetAddress address = InetAddress.getByName(ip); //如果输入的是主机名,尝试获取ip地址
   Socket socket;//定义套接字
   SocketAddress socketAddress;//传递ip和端口
   if (ports.length < 1)
    //若数组没有元素,返回,不执行
    return;
   for (port = 0 + serial; port <= ports.length - 1; port += threadNumber) {
    //每次运行10个线程
    socket = new Socket();
    //为对象分配内存空间
    socketAddress = new InetSocketAddress(address, ports[port]);
    try {
     socket.connect(socketAddress, timeout);
     //对目标主机的指定端口进行连接,超时后连接失败
     socket.close();
     //关闭端口
     System.out.println("端口 " + ports[port] + " :开放");
     jta.append("端口 " + ports[port] + " :开放\n");
     //在文本区域里更新消息
    } catch (IOException e) {
     System.out.println("端口 " + ports[port] + " :关闭");
     jta.append("端口 " + ports[port] + " :关闭\n");
     //产生异常表示端口关闭
    }
   }
  } catch (UnknownHostException e) {
   e.printStackTrace();
  }
 }
 //end of run()
}//end of ScanMethod
public JPanel getPanel() {
 JPanel jp = new JPanel();
 jp.add(jb1, BorderLayout.CENTER);
 jp.setBorder(BorderFactory.createRaisedBevelBorder());
 jp.setBackground(Color.lightGray);
 return jp;
}
public JPanel getPanel2() {
 JPanel jp = new JPanel();
 JLabel jl = new JLabel();
 jl.setText("请输入主机名或ip地址,将扫描该主机的常见端口号:");
 jp.add(jl);
 jp.add(jtf);
 jp.setBorder(BorderFactory.createRaisedBevelBorder());
 jp.setBackground(Color.LIGHT_GRAY);
 return jp;
}
public JPanel getPanel3() {
 JLabel jl1 = new JLabel(str1);
 JLabel jl2 = new JLabel(str2);
 JLabel jl3 = new JLabel(str3);
 JLabel jl4 = new JLabel(str4);
 JLabel jl5 = new JLabel(str5);
 JLabel jl6 = new JLabel(str6);
 JPanel jp = new JPanel();
 jp.setLayout(new GridLayout(6, 1));
 jp.add(jl1);
 jp.add(jl2);
 jp.add(jl3);
 jp.add(jl4);
 jp.add(jl5);
 jp.add(jl6);
 jp.setBorder(BorderFactory.createEtchedBorder());
 //蚀刻边框
 return jp;
}
public static void main(String[] args) {
 new ScanPort();
}
}

希望本文所述对大家java程序设计有所帮助。

来源:https://blog.csdn.net/wangbowj123/article/details/76473065

0
投稿

猜你喜欢

  • 1 场景启动器 starter 简介什么是 SpringMVC在早期 Java Web 的开发中,统一把显示层、控制层、数据层的操作全部交给
  • 一、简介上篇介绍了一个自己做的管理系统,最近空闲的时间自己在继续做,把之前登录时候自定义的 * 过滤器换成了基于SpringSecurity
  • 创建我们来看看,使用Arrays 怎么创建一个新的数组,一般来说,我们可以使用Arrays 的 copyOf , copyOfRange 和
  • 本文是利用C# 实现FTP客户端的小例子,主要实现上传,下载,删除等功能,以供学习分享使用。思路:通过读取FTP站点的目录信息,列出对应的文
  • 目录前言应用定义基本Enum特性Enum的静态导入Enum中添加新方法Switch语句中的EnumEnum的继承EnumSet的使用Enum
  • JAVA关键字final用于修饰数据、方法或类,通常意味着“无法改变的”,既数据不能改变,方法不能覆盖,类不能继承。一般采用final有两种
  • Android手机或平板都会存在横竖屏切换的功能,通常是由物理重力感应触发的,但是有时候也不尽然,通常在设置里面我们可以对手机的横竖屏切换进
  • 常量,顾名思义,就是“不会改变的量”。我们平时书写的数字(比如12.85)、字符(比如'F')、字符串(比如"谢谢
  • 局限性只支持MP4文件经过尝试对于一些MP4文件分割不了依赖<!-- mp4文件操作jar --><!-- https:/
  • 问题提出:自己在做一个小网站充当练手,但是前端图片经过base64加密后传往后端在解码。但是一直都有问题,请大神赐教  publi
  • 1、线性表定义线性表是最基本、最简单、也是最常用的一种数据结构。线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特
  • 最近需要做一个类似于电话客户的功能,要求拨打电话能自动录音。所以写了一个dome,希望能够帮到大家。主要思路就是监听手机通话状态在监听到接听
  • 1. JWT的概念和特点JWT是一种轻量级、可扩展、可自包含的身份验证和授权机制。它是由三个部分组成:头部(Header)、载荷(Paylo
  • 1.概览该教程中,我将向你展示:如何在测试时设置spring boot 日志级别。虽然我们可以在测试通过时忽略日志,但是如果需要诊断失败的测
  • 一、概述xml整合第三方框架有两种整合方案:不需要自定义名空间,不需要使用Spring的配置文件配置第三方框架本身内容,例如:MyBatis
  • /** * 三角数字: * 比达哥斯拉领导下的古希腊数学家发现了一个有趣的数字序列1, 3, 6, 10, 15, 21,... *
  • 主题 ActiveMQ Spring Boot 小程序开发1.引入依赖<parent><groupId>org.sp
  • 本文实例为大家分享了Flutter自定义圆盘取色器的具体代码,供大家参考,具体内容如下下面展示一些 内联代码片。圆盘取色器效果图完整代码im
  • Java 线程同步根本上是要符合一个逻辑:加锁------>修改------>释放锁1、同步代码块示例如下:public cla
  • 本文实例讲述了C#实现用于操作wav声音文件的类。分享给大家供大家参考。具体如下:有了这个C#类,我们可以很轻易的调用本地wav文件进行同步
手机版 软件编程 asp之家 www.aspxhome.com