虚位以待(AD)
虚位以待(AD)
首页 > 软件编程 > Java编程 > Java网络编程实现的简单端口扫描器示例

Java网络编程实现的简单端口扫描器示例
类别:Java编程   作者:码皇   来源:互联网   点击:

这篇文章主要介绍了Java网络编程实现的简单端口扫描器,涉及Java网络编程Socket组建、swing组建及多线程相关操作技巧,需要的朋友可以参考下

本文实例讲述了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相关内容感兴趣的读者可查看本站专题:《Java网络编程技巧总结》、《Java Socket编程技巧总结》、《Java文件与目录操作技巧汇总》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》和《Java缓存操作技巧汇总

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

您可能感兴趣的文章:

  • java网络编程之socket网络编程示例(服务器端/客户端)
  • java网络编程中向指定URL发送GET POST请求示例
  • 简单介绍Java网络编程中的HTTP请求
  • java网络编程学习java聊天程序代码分享
  • 简单讲解Java的Socket网络编程的多播与广播实现
  • Java网络编程基础教程之Socket入门实例
  • Java套接字(Socket)网络编程入门
  • Java的Socket网络编程基础知识入门教程
  • java替换url的域名和端口方法
  • Java查看本机端口是否被占用源码
相关热词搜索: Java 网络编程 端口扫描器