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

转载请注明原始链接

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