how to force unclosed Jsch ssh connections to close

孤街浪徒 提交于 2019-12-11 08:03:35

问题


I'm using Jsch and expectit to connect to network devices and update configs, change passwords, etc...

I am having a problem where loopback connections remain open which prevents more ssh sessions from being created. I read that this is a problem with certain versions of OpenSSH and that the solution is to upgrade the sshd. Unfortunately this sometimes isn't an option when connecting to network appliances.

Is there no workaround?

EDIT - Here's my code - aren't I closing everything manually?

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();

回答1:


It turns out the loopback connections that weren't closing were being created by my IDE - IntelliJ IDEA. When I deployed the classes to a UNIX machine and ran it, there were no lingering loopback connections and no issues with running out of them.




回答2:


Here is my response to the same question asked here.

The channel does not close itself when there is no input left. Try closing it yourself after you have read all data.

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){}
}

The only time you are going to use a loop that doesnt manually close the channel is when you have interactive keyboard input from the user. Then when the user does an 'exit' that will change the channel's 'getExitStatus'. If your loop is while(channel.getExitStatus() == -1) then the loop will exit when the user has exited. You still need to disconnect the channel and session yourself after you detect an Exit Status.

It is not listed on their example page, but JSCH hosts an interactive keyboard demo on their site. http://www.jcraft.com/jsch/examples/UserAuthKI.java

Even their demo, which I used to connect to an AIX system without changing any of their code... does not close when you exit the shell!

I had to add the following code to get it to exit properly after I had typed 'exit' in my remote session:

         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);
   }
}


来源:https://stackoverflow.com/questions/27847599/how-to-force-unclosed-jsch-ssh-connections-to-close

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!