如何强制关闭未关闭的 Jsch ssh 连接

how to force unclosed Jsch ssh connections to close

我正在使用 Jsch 并期望它连接到网络设备并更新配置、更改密码等...

我遇到了一个问题,即环回连接保持打开状态,这会阻止创建更多 ssh 会话。我读到这是某些版本的 OpenSSH 的问题,解决方案是升级 sshd。不幸的是,当连接到网络设备时,这有时不是一个选项。

没有解决办法吗?

编辑 - 这是我的代码 - 我不是手动关闭所有内容吗?

JSch jSch = new JSch();
Session session = jSch.getSession("username", h.hostname);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setPassword("password");
session.connect();
Channel channel = session.openChannel("shell");

Expect expect = new ExpectBuilder()
                .withOutput(channel.getOutputStream())
                .withInputs(channel.getInputStream(), channel.getExtInputStream())
                .withEchoOutput(System.out)
                .withEchoInput(System.err)
                .withExceptionOnFailure()
                .build();
channel.connect();
expect.expect(contains("#"));
expect.sendLine("showRules\r");
String response = expect.expect(regexp("#")).getBefore();
System.out.println("---" + response + "----");
expect.sendLine("exit\r");
expect.close();

channel.disconnect();
session.disconnect();

这是我对同一问题的回答 here.

当没有剩余输入时,频道不会自行关闭。读取所有数据后尝试自行关闭。

while (true) {
    while (inputStream.available() > 0) {
        int i = inputStream.read(buffer, 0, 1024);
        if (i < 0) {
            break;
        }
        //It is printing the response to console
        System.out.print(new String(buffer, 0, i));
    }
    System.out.println("done");

    channel.close();  // this closes the jsch channel

    if (channel.isClosed()) {
        System.out.println("exit-status: " + channel.getExitStatus());
        break;
    }
    try{Thread.sleep(1000);}catch(Exception ee){}
}

唯一一次你要使用不手动关闭频道的循环是当你有来自用户的交互式键盘输入时。然后,当用户执行 'exit' 时,将更改频道的 'getExitStatus'。如果您的循环是 while(channel.getExitStatus() == -1) 则当用户退出时循环将退出。您仍然需要在检测到退出状态后自行断开频道和会话。

它没有列在他们的示例页面上,但 JSCH 在他们的网站上提供了一个交互式键盘演示。 http://www.jcraft.com/jsch/examples/UserAuthKI.java

即使是他们的演示,我曾经在不更改任何代码的情况下连接到 AIX 系统...当您退出 shell!

时也不会关闭

我必须添加以下代码才能在远程会话中键入 'exit' 后使其正确退出:

         channel.connect();

         // My added code begins here
         while (channel.getExitStatus() == -1){
            try{Thread.sleep(1000);}catch(Exception e){System.out.println(e);}
         }

         channel.disconnect();
         session.disconnect();
         // My Added code ends here

       }

   catch(Exception e){
     System.out.println(e);
   }
}

原来没有关闭的环回连接是由我的 IDE - IntelliJ IDEA 创建的。当我将 类 部署到 UNIX 机器并 运行 它时,没有挥之不去的环回连接,其中 运行 也没有问题。