无法获取端口上的服务详细信息?

时间:2018-07-01 12:10:01

标签: java

我希望获得端口中正在使用的服务名称。但是,我无法。我要做的是检查是否使用了端口。如果使用它,那么我想获取该端口上的服务详细信息。我怎样才能做到这一点以及我做错了什么?

public int checkPort(int port){
    try {
        InetAddress inetAddress = InetAddress.getLocalHost();
        ss = new Socket(inetAddress.getHostAddress(), port);
        if(ss.isBound()) {
            System.out.println("Port " + port + " is being used by ");

            Process p1 = Runtime.getRuntime().exec("grep -w " + port + " /etc/services");
            p1.waitFor();

            BufferedReader reader = new BufferedReader(new InputStreamReader(p1.getInputStream()));
            String line = reader.readLine();
            while(line != null) {
                System.out.println(line);
                line = reader.readLine();
            }
        }
        ss.close();
    } catch (Exception e) {
        System.out.println("Port " +port+ " is not being used");
    }
    return 0;
}

结果

  

端口139被

使用      

未使用端口139

1 个答案:

答案 0 :(得分:0)

好吧,假设您使用的是Windows(在其他操作系统上可能有所不同),则可能会遇到此异常。

  

无法运行程序“ grep”:CreateProcess error = 2,系统找不到指定的文件

至少,这就是我得到的。您可能会得到一个完全不同的错误。这里的主要问题是,有一个大的try catch块没有e.printStackTrace(),它捕获了每个异常。这意味着当出现错误时,无法知道原因。

希望这对您有用。具有讽刺意味的是,您不需要套接字即可测试端口上的服务,因此它可能是XY problem

我在端口上查找服务的解决方案如下。

SocketTester.java

package socket;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;

/**
 * An answer for <a href="https://stackoverflow.com/questions/51123167/unable-to-get-service-details-on-port">Unable to get service details on port?</a>
 * 
 * @see <a href="https://stackoverflow.com/questions/51123167/unable-to-get-service-details-on-port">Unable to get service details on port?</a>
 * @version 1.0
 * @author Dan
 */

public class SocketTester {
    /**
     * This method checks whether a port is being used by any services.
     * It will output any information to the system console.
     * 
     * @param port The port to be checked for any services
     */
    public static void checkPort(int port) {
        TreeSet<String> pids = null;
        List<Service> services = null;

        pids = getPIDs(port);

        if(pids != null) {
            services = getServices(port, pids);
        }

        listInformation(port, services);
    }

    /**
     * This method checks whether there are any PIDs on the specified port.
     * If there are these are then returned.
     * 
     * @param port The port to check for PIDs
     * @return It returns a TreeSet containing any found PIDs on the specified port
     */
    private static TreeSet<String> getPIDs(int port) {
        TreeSet<String> returnVal = new TreeSet<String>();

        ProcessBuilder pidProcessBuilder = new ProcessBuilder("cmd.exe", "/C", "netstat -ano | find \"" + port + "\"");
        pidProcessBuilder.redirectErrorStream(true);

        Process pidProcess = null;
        try {
            pidProcess = pidProcessBuilder.start();
        } catch (IOException e) {
            return null;
        }

        BufferedReader pidProcessOutputReader = new BufferedReader(new InputStreamReader(pidProcess.getInputStream()));
        String outputLine = null;

        try {
            outputLine = pidProcessOutputReader.readLine();
        } catch (IOException e) {
            return null;
        }

        while (outputLine != null) {
            List<String> outputLineParts = new ArrayList<String>(Arrays.asList(outputLine.split(" ")));
            outputLineParts.removeAll(Arrays.asList(""));

            //outputLineParts.get(1) is the local address. We don't want a foreign address to accidently be found
            //outputLineParts.size() - 1 is the PID
            if(outputLineParts.get(1).contains(":" + port) && !returnVal.contains(outputLineParts.get(outputLineParts.size() - 1))) {
                returnVal.add(outputLineParts.get(outputLineParts.size() - 1));
            }

            try {
                outputLine = pidProcessOutputReader.readLine();
            } catch (IOException e) {
                return null;
            }
        }

        try {
            pidProcess.waitFor();
        } catch (InterruptedException e) {
            return null;
        }

        return returnVal;
    }

    /**
     * This method checks whether there are any services related to the PID.
     * If there are these are then returned.
     * 
     * @param port A reference to the PIDs port
     * @param pids A list of PIDs found by getPIDs
     * @return It returns a List containing any found services on the specified PIDs
     */
    private static List<Service> getServices(int port, TreeSet<String> pids) {
        List<Service> returnVal = new ArrayList<Service>();

        for(String pid : pids) {
            ProcessBuilder serviceProcessBuilder = new ProcessBuilder("cmd.exe", "/C", "tasklist /svc /FI \"PID eq " + pid + "\" | find \"" + pid + "\"");
            serviceProcessBuilder.redirectErrorStream(true);

            Process serviceProcess = null;
            try {
                serviceProcess = serviceProcessBuilder.start();
            } catch (IOException e) {
                return null;
            }

            BufferedReader serviceProcessOutputReader = new BufferedReader(new InputStreamReader(serviceProcess.getInputStream()));
            String outputLine = null;

            try {
                outputLine = serviceProcessOutputReader.readLine();
            } catch (IOException e) {
                return null;
            }

            while(outputLine != null) {
                List<String> outputLineParts = new ArrayList<String>(Arrays.asList(outputLine.split(" ")));
                outputLineParts.removeAll(Arrays.asList(""));

                //outputLineParts.get(0) is the service
                returnVal.add(new Service(port, pid, outputLineParts.get(0)));

                try {
                    outputLine = serviceProcessOutputReader.readLine();
                } catch (IOException e) {
                    return null;
                }
            }

            try {
                serviceProcess.waitFor();
            } catch (InterruptedException e) {
                return null;
            }
        }
        return returnVal;
    }

    /**
     * This method lists the information found by checkPort
     * 
     * @param port The port that has been checked for services
     * @param servicesRunning The services found on the port
     */
    private static void listInformation(int port, List<Service> servicesRunning) {
        if(servicesRunning != null && servicesRunning.size() != 0) {
            System.out.println("The following services are being run on port " + port);
            for(Service service : servicesRunning) {
                System.out.println("\t" + service.getService());
            }
        } else {
            System.out.println("There are no services being run on port " + port);
        }
    }

    public static void main(String[] args) {
        final int portToCheck = 135;
        checkPort(portToCheck);
    }
}

Sevice.java

package socket;

/**
 * An supplementary class to support SocketTester
 * 
 * @see <a href="https://stackoverflow.com/questions/51123167/unable-to-get-service-details-on-port">Unable to get service details on port?</a>
 * @version 1.0
 * @author Dan
 */

public class Service {
    private int port;
    private String pid;
    private String service;

    public Service(int port, String pid, String service) {
        this.port = port;
        this.pid = pid;
        this.service = service;
    }

    public int getPort() {
        return port;
    }

    public String getPID() {
        return pid;
    }

    public String getService() {
        return service;
    }

    @Override
    public String toString() {
        return "Service \"" + "\" is being run on port " + port + " and has the PID " + pid;
    }
}