使用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(); } }
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。