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

网友投稿 377 2023-02-08


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 portList = new LinkedList();// 定义一个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 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 portList; // 待扫描的端口的List集合

private int threadNumber, serial, timeout; // 线程数,这是第几个线程,超时时间

public ScanMethod(String ip, List 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)

//若数组没有元素,返回DILGSG,不执行

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程序设计有所帮助。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:如何以Angular的姿势打开Font
下一篇:私有化api接口管理(开源api接口管理工具)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~