我们之前在网上常见的java判断端口号占用的方法都是通过建立一个socket来判断。这个方法效率很低。对于要获取多个端口是否被监听,即使采用了多线程 也特别慢。
那么我们换一种思路。
结合我之前写过的两篇文章linux 查看端口是否被占用和javaSSHlinux主机并执行命令获取控制台结果
我们可以实现查看远程linux主机已经被TCP监听的端口。
import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.Charset; import java.util.Properties; import com.jcraft.jsch.ChannelExec; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; public class SSHConnector { public static void main(String[] args) throws Exception { JSch jsch = new JSch(); // 创建JSch对象 String userName = "root";// 用户名 String password = "root";// 密码 String host = "192.168.1.12";// 服务器地址 int port = 22;// 端口号 String cmd = "netstat -tnl";// 要运行的命令 Session session = jsch.getSession(userName, host, port); // 根据用户名,主机ip,端口获取一个Session对象 session.setPassword(password); // 设置密码 Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); // 为Session对象设置properties int timeout = 60000000; session.setTimeout(timeout); // 设置timeout时间 session.connect(); // 通过Session建立链接 ChannelExec channelExec = (ChannelExec) session.openChannel("exec"); channelExec.setCommand(cmd); channelExec.setInputStream(null); channelExec.setErrStream(System.err); channelExec.connect(); InputStream in = channelExec.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in, Charset.forName("UTF-8"))); String buf = null; StringBuffer sb = new StringBuffer(); while ((buf = reader.readLine()) != null) { sb.append(buf); System.out.println(buf);// 打印控制台输出 } reader.close(); channelExec.disconnect(); if (null != session) { session.disconnect(); } } }
我们可以获取结果示例如下:
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:111 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 192.168.122.1:53 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:801 0.0.0.0:* LISTEN
tcp6 0 0 :::61613 :::* LISTEN
tcp6 0 0 :::111 :::* LISTEN
tcp6 0 0 :::61616 :::* LISTEN
tcp6 0 0 :::21 :::* LISTEN
tcp6 0 0 :::22 :::* LISTEN
tcp6 0 0 ::1:631 :::* LISTEN
tcp6 0 0 ::1:25 :::* LISTEN
tcp6 0 0 :::1883 :::* LISTEN
tcp6 0 0 127.0.0.1:8161 :::* LISTEN
tcp6 0 0 :::5445 :::* LISTEN
tcp6 0 0 :::5672 :::* LISTEN
这时我们只要通过java对字符串进行切割和解析,即可获取所有被监听的端口号了。