我们之前在网上常见的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对字符串进行切割和解析,即可获取所有被监听的端口号了。