java實現調用nc命令檢測遠程服務器端口可用性

第一種方法:使用nc命令

原理:

nc命令:
nc host port
當遠程host的port被佔用時,會形成一個臨時的會話,命令阻塞;
Port未被佔用,命令執行通過,不會阻塞;

Process類:

ProcessBuilder.start() 和 Runtime.exec 方法創建一個本機進程,並返回 Process 子類的一個實例,該實例可用來控制進程並獲得相關信息。Process 類提供了執行從進程輸入、執行輸出到進程、等待進程完成、 檢查進程的退出狀態以及銷燬(殺掉)進程的方法。創建進程的方法可能無法針對某些本機平臺上的特定進程很好地工作,比如,本機窗口進程,守護進程,Microsoft Windows 上的 Win16/DOS 進程,或者 shell 腳本。創建的子進程沒有自己的終端或控制檯。它的所有標準 io(即 stdin、stdout 和 stderr)操作都將通過三個流 (getOutputStream()、getInputStream() 和 getErrorStream()) 重定向到父進程。父進程使用這些流來提供到子進程的輸入和獲得從子進程的輸出。因爲有些本機平臺僅針對標準輸入和輸出流提供有限的緩衝區大小,如果讀寫子進程的輸出流或輸入流迅速出現失敗,則可能導致子進程阻塞,甚至產生死鎖。當沒有 Process 對象的更多引用時,不是刪掉子進程,而是繼續異步執行子進程。對於帶有 Process 對象的 Java 進程,沒有必要異步或併發執行由 Process 對象表示的進程。

process 方法:

Process exec(String command) 在單獨的進程中執行指定的字符串命令。
Process exitValue() 返回子進程的出口值。根據慣例,值0表示正常終止

相關代碼:

/*
 * 測試類
 */
public class PortsUtils {

    /**
     * check one port
     * overtimes
     * windows下設置不小於1200ms
     * linux下設置不小於100ms
     *
     * @param overtimes
     * @param ip
     * @param port
     * @return
     * @throws IOException
     */
    public static boolean checkPort(long overtimes, String ip, int port) throws ExecutionException, InterruptedException {
        Process process;
        try {
            process = Runtime.getRuntime().exec("nc " + ip + " " + port);
        } catch (IOException e) {
            e.printStackTrace();
            return true;
        }
        sleep(overtimes);
        try {
            process.exitValue();
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return true;
        }
    }

    /**
     * 驗證多個端口 設置延遲3s
     *
     * @param ips
     * @param minPort
     * @param maxPort
     * @return
     * @throws IOException
     */
    public static boolean checkPorts(List<String> ips, int minPort, int maxPort) {
        List<PortChecker> portCheckers = new ArrayList<>();
        for (String ip : ips) {
            for (int port = minPort; port <= maxPort; port++) {
                Process process;
                try {
                    process = Runtime.getRuntime().exec("nc " + ip + " " + port);
                } catch (IOException e) {
                    e.printStackTrace();
                    return true;
                }
                PortChecker portChecker = new PortChecker(ip, port, process);
                portCheckers.add(portChecker);
            }
        }
        sleep(3000);
        List<String> occupiedPorts = new ArrayList<>();
        for (PortChecker portChecker : portCheckers) {
            try {
                portChecker.getProcess().exitValue();
            } catch (Exception e) {
                occupiedPorts.add(portChecker.getIp() + ":" + portChecker.getPort());
                portChecker.getProcess().destroy();
                continue;
            }
        }
        System.out.println(occupiedPorts.toString());
        return !occupiedPorts.isEmpty();
    }

    private static void sleep(long times) {
        try {
            Thread.sleep(times);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

/*
 * bean
 */
public class PortChecker {

    private String ip;
    private int port;
    private Process process;

    public PortChecker(String ip, int port, Process process) {
        this.ip = ip;
        this.port = port;
        this.process = process;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public Process getProcess() {
        return process;
    }

    public void setProcess(Process process) {
        this.process = process;
    }
}

測試:

這裏寫圖片描述

第二種方法:使用socket

原理:

創建 Socket 對象來檢查主機上打開或正在使用的端口。

相關代碼:

/*
 * 測試類
 */
public class CheckPort {

    public static boolean check(String host, int port) {
        try {
            Socket socket = new Socket(host, port);
            socket.close();
        } catch (IOException e) {
            System.out.println("未佔");
            return false;
        }
        System.out.println("被佔");
        return true;
    }
}

附 錄##

linux nc 安裝: yum install nc
這裏寫圖片描述

windows nc安裝:
使用安裝版的nmap時注意把安裝目錄中的ncat.exe改爲nc.exe,並配置環境變量;
下載地址:http://download.csdn.net/download/sunshine1991mo/10113065

轉載請註明原始鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章