溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用Java怎么實(shí)現(xiàn)一個(gè)端口掃描器

發(fā)布時(shí)間:2021-01-22 16:23:16 來源:億速云 閱讀:200 作者:Leah 欄目:編程語言

使用Java怎么實(shí)現(xiàn)一個(gè)端口掃描器?很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

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 {
 /**
  * 端口掃描啟動(dòng)主程序
  */
 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>();// 定義一個(gè)List容器表示掃描的團(tuán)口的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("標(biāo)楷體", Font.BOLD, 16));
  jta.setLineWrap(true);// 激活自動(dòng)換行功能
  jta.setWrapStyleWord(true);// 激活斷行不斷字功能
  portList.addAll(Arrays.asList(ports));
  //將ports中的值加入到set中,并去掉重復(fù)的
  jb1.addActionListener(new ActionListener() {
   @Override
   public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    IP = jta.getText();
    //ip為文本框內(nèi)輸入的字符串
    scanPorts(IP, portList, 10, 800);
    //超時(shí)時(shí)間設(shè)定為800,線程數(shù)設(shè)定為10
   }
  });
  this.setVisible(true);
 }
 /**
  * 多線程掃描目標(biāo)主機(jī)指定List端口集合的開放情況
  *
  * @param ip
  *   待掃描IP或域名
  * @param portList
  *   待掃描的端口的List集合
  * @param threadNumber
  *   線程數(shù)
  * @param timeout
  *   連接超時(shí)時(shí)間
  * */
 public void scanPorts(String ip, List<Integer> portSet,int threadNumber, int timeout) {
  ExecutorService threadPool = Executors.newCachedThreadPool();
  //線程池
  for (int i = 0; i < threadNumber; i++) {
   //10個(gè)線程 加入到線程池里
   ScanMethod scanMethod2 = new ScanMethod(ip, portSet,threadNumber, i, timeout);
   threadPool.execute(scanMethod2);
  }
  threadPool.shutdown();
  while (true) {
   if (threadPool.isTerminated()) {
    System.out.println("掃描結(jié)束");
    break;
   }
   try {
    Thread.sleep(1000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
  }// end of while
 }
 /*
  * 掃描方式:針對(duì)一個(gè)待掃描的端口的List集合進(jìn)行掃描
  */
 private class ScanMethod implements Runnable {
  private String ip; // 目標(biāo)IP
  private List<Integer> portList; // 待掃描的端口的List集合
  private int threadNumber, serial, timeout; // 線程數(shù),這是第幾個(gè)線程,超時(shí)時(shí)間
  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轉(zhuǎn)數(shù)組
   try {
    InetAddress address = InetAddress.getByName(ip); //如果輸入的是主機(jī)名,嘗試獲取ip地址
    Socket socket;//定義套接字
    SocketAddress socketAddress;//傳遞ip和端口
    if (ports.length < 1)
     //若數(shù)組沒有元素,返回,不執(zhí)行
     return;
    for (port = 0 + serial; port <= ports.length - 1; port += threadNumber) {
     //每次運(yùn)行10個(gè)線程
     socket = new Socket();
     //為對(duì)象分配內(nèi)存空間
     socketAddress = new InetSocketAddress(address, ports[port]);
     try {
      socket.connect(socketAddress, timeout);
      //對(duì)目標(biāo)主機(jī)的指定端口進(jìn)行連接,超時(shí)后連接失敗
      socket.close();
      //關(guān)閉端口
      System.out.println("端口 " + ports[port] + " :開放");
      jta.append("端口 " + ports[port] + " :開放\n");
      //在文本區(qū)域里更新消息
     } catch (IOException e) {
      System.out.println("端口 " + ports[port] + " :關(guān)閉");
      jta.append("端口 " + ports[port] + " :關(guān)閉\n");
      //產(chǎn)生異常表示端口關(guā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("請(qǐng)輸入主機(jī)名或ip地址,將掃描該主機(jī)的常見端口號(hào):");
  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();
 }
}

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI