最近需要读取和修改华为路由器的配置,使用Java语言开发,通过SSH连接,输入命令并读取响应。

1.添加mwiede/jsch依赖

  • 如果使用Maven,可以在pom.xml文件中添加以下依赖:
    1
    2
    3
    4
    5
    6
    7
    <dependencies>
    <dependency>
    <groupId>com.github.mwiede</groupId>
    <artifactId>jsch</artifactId>
    <version>0.2.15</version>
    </dependency>
    </dependencies>
  • 如果使用Gradle,则添加到build.gradle文件:
    1
    2
    3
    dependencies {
    implementation 'com.github.mwiede:jsch:0.2.15'
    }

2.使用Jsch创建SSH连接,输入命令并返回响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/** 
* 获取SSH命令响应
* @param userName 用户名
* @param password 密码
* @param host ip地址
* @param port 端口
* @param commandList 命令列表
*/
public String getShellCmdRes(String userName, String password, String host, Integer port, List<String> commandList) throws JSchException, IOException {
StringBuilder stringBuilder = new StringBuilder();
JSch jsch = new JSch();
Session session = jsch.getSession(userName, host, port());
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();

ChannelShell channel = (ChannelShell) session.openChannel("shell");

// 获取输入输出流
OutputStream inputStreamForTheChannel = channel.getOutputStream();
InputStream outputStreamForTheChannel = channel.getInputStream();

// 连接通道
channel.connect();

PrintStream commander = new PrintStream(inputStreamForTheChannel, true);

byte[] tmp = new byte[1024];
while (true) {
while (outputStreamForTheChannel.available() > 0) {
int i = outputStreamForTheChannel.read(tmp, 0, 1024);
if (i < 0) {
break;
}
String output = new String(tmp, 0, i);
// 读取响应
stringBuilder.append(output);
stringBuilder.append(System.lineSeparator());
// 发送命令
commandList.forEach(command -> {
commander.println(command);
});
}
if (channel.isClosed()) {
if (outputStreamForTheChannel.available() > 0) {
continue;
}
break;
}
try {
Thread.sleep(10);
} catch (Exception ee) {
}
}

// 关闭通道和会话
channel.disconnect();
session.disconnect();
return stringBuilder.toString();
}

3.调用上文方法

3.1 单条命令

记得结束时加入退出语句,这里以路由器为例,用quit退出

1
2
3
4
5
6
7
List<String> commandList = new  ArrayList<>();
// 查看
commandList.add("display bfd session all");
// 退出会话
commandList.add("quit");
// 获取响应
String response = getShellCmdRes("admin", "admin", "1.1.1.1", 22, List<String> commandList)

本地图片

3.2 多条命令

如果是多条命令,每进入一个会话,就多一个退出语句

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
List<String> commandList = new ArrayList<>();
// 进入system-view
commandList.add("system-view");
// 进入Tunnel 0/0/5
commandList.add("interface Tunnel 0/0/5");
// 查看信息
commandList.add("display this");
// 退出Tunnel 0/0/5
commandList.add("quit");
// 退出system-view
commandList.add("quit");
// 退出会话
commandList.add("quit");
// 获取响应
String response = getShellCmdRes("admin", "admin", "1.1.1.1", 22, List<String> commandList)

本地图片