问题
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