使用java代碼關閉指定端口的程序-windows


轉載請請在頁首注明作者與出處

 

一:問題由史

今天遇到一個問題,就是在實現自動化災備的時候,發現原有死掉的程序沒有完全關閉,當然這都不是本文的重點,重點是這個時候,我得把它完全關閉,所以才有了這篇文章。

 

 

 

二:基礎知識

 

2.1:java要怎么實現

java可以獲取並刪除JAVA虛擬機啟動的應用,但是卻並沒有提供API獲取操作系統中其它的進程的API。

但是java可以執行操作系統的腳本命令。

 

2.2:根據端口查找進程

windows中有這樣的命令

netstat -ano   查看操作系統所有占用端口的進程

  

netstat -ano | findstr "8080" 獲取占用了80端口的進程

得到的結果如下

 TCP    127.0.0.1:51846        127.0.0.1:5037         TIME_WAIT       0
 TCP    127.0.0.1:51847        127.0.0.1:5037         TIME_WAIT       0
UDP    0.0.0.0:4500           *:*                                    444
UDP    0.0.0.0:5355           *:*                                    1232

 

可以看到TCP/UPD是所使用的協議,后面的是綁定IP與端口,最后一列,是占用的進程號(pid)。

 

 

2.3:根據進程號刪除進程

再來看一條命令

taskkill /pid 123

我們可以關閉進程號為123的進程,當然,我試上面的這條命令的時候,系統提示無法終止這個進程,那我們可以加一個/F,如下,就能強行關閉。

taskkill /F /pid 123

 

 

三:java實現,支持一次性殺死多個端口

之前有說過,java可以執行操作系統的腳本,不論是什么操作,系統,那么我們就可以用這個方法,來直接執行這些命令來達到相應的效果。

 

package kill.window;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class KillServer {
    private Set<Integer> ports;

    public static void main(String[] args) throws InterruptedException {
        System.out.println("請輸入要殺掉的windows進程的端口號,如果有多個,則以逗號相隔");
        System.out.println("Please input kill port");
        Scanner scanner = new Scanner(System.in);
        String input = scanner.next();
        scanner.close();
        String[] split = input.split(",");
        Set<Integer> ports = new HashSet<>();
        for (String spid : split) {
            try{
                int pid = Integer.parseInt(spid);
                ports.add(pid);
            }catch(Exception e){
                System.out.println("錯誤的端口號,請輸入一個或者多個端口,以英文逗號隔開");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                System.exit(0);
            }
        }
        
        KillServer kill = new KillServer();
        kill.ports = ports;
        System.out.println("need kill " + ports.size() + " num");
        for (Integer pid : ports) {
            kill.start(pid);
        }
        System.out.println("清理完畢,程序即將退出");
        System.out.println("SUCCESS");
        Thread.sleep(5000);
        System.exit(0);
        
    }
    
    public void start(int port){
        Runtime runtime = Runtime.getRuntime();
        try {
            //查找進程號
            Process p = runtime.exec("cmd /c netstat -ano | findstr \""+port+"\"");
            InputStream inputStream = p.getInputStream();
            List<String> read = read(inputStream, "UTF-8");
            if(read.size() == 0){
                System.out.println("找不到該端口的進程");
                try {
                    Thread.sleep(6000);
                    System.exit(0);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                for (String string : read) {
                    System.out.println(string);
                }
                System.out.println("找到"+read.size()+"個進程,正在准備清理");
                kill(read);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }
    
    /**
     * 驗證此行是否為指定的端口,因為 findstr命令會是把包含的找出來,例如查找80端口,但是會把8099查找出來
     * @param str
     * @return
     */
    private boolean validPort(String str){
        Pattern pattern = Pattern.compile("^ *[a-zA-Z]+ +\\S+");
        Matcher matcher = pattern.matcher(str);

        matcher.find();
        String find = matcher.group();
        int spstart = find.lastIndexOf(":");
        find = find.substring(spstart + 1);
        
        int port = 0;
        try {
            port = Integer.parseInt(find);
        } catch (NumberFormatException e) {
            System.out.println("查找到錯誤的端口:" + find);
            return false;
        }
        if(this.ports.contains(port)){
            return true;
        }else{
            return false;
        }
    }
    
    /**
     * 更換為一個Set,去掉重復的pid值
     * @param data
     */
    public void kill(List<String> data){
        Set<Integer> pids = new HashSet<>();
        for (String line : data) {
            int offset = line.lastIndexOf(" ");
            String spid = line.substring(offset);
            spid = spid.replaceAll(" ", "");
            int pid = 0;
            try {
                pid = Integer.parseInt(spid);
            } catch (NumberFormatException e) {
                System.out.println("獲取的進程號錯誤:" + spid);
            }
            pids.add(pid);
        }
        killWithPid(pids);
    }
    
    /**
     * 一次性殺除所有的端口
     * @param pids
     */
    public void killWithPid(Set<Integer> pids){
        for (Integer pid : pids) {
            try {
                Process process = Runtime.getRuntime().exec("taskkill /F /pid "+pid+"");
                InputStream inputStream = process.getInputStream();
                String txt = readTxt(inputStream, "GBK");
                System.out.println(txt);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    private List<String> read(InputStream in,String charset) throws IOException{
        List<String> data = new ArrayList<>();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset));
        String line;
        while((line = reader.readLine()) != null){
            boolean validPort = validPort(line);
            if(validPort){
                data.add(line);
            }
        }
        reader.close();
        return data;
    }
    public String readTxt(InputStream in,String charset) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(in, charset));
        StringBuffer sb = new StringBuffer();
        String line;
        while((line = reader.readLine()) != null){
            sb.append(line);
        }
        reader.close();
        return sb.toString();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM