2015-01-08 77 views
1

我使用Jsch和expectit连接到网络设备和更新CONFIGS,更改密码等..如何强制未闭合Jsch SSH连接关闭

我有哪里回环连接保持开放的一个问题,阻止创建更多的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(); 
+0

你所指的问题不会与我发出任何响铃。也许你可以向我们展示一些有问题的代码并解释问题所在。 – Kenster

+0

在您编辑的代码中,当您完成所有代码时,您似乎正在关闭所有内容。什么是实际问题?你有什么不好的行为? – Kenster

+0

经过约180次连接之后,我开始出现IOException异常:“无法建立环回连接”。当我执行netstat -na时,在TIME_WAIT状态下127.0.0.1上有100个连接。在这些关闭之前,我无法建立更多的ssh连接。 –

回答

2

事实证明,没有关闭正在创建的环回连接通过我的IDE - IntelliJ IDEA。当我将这些类部署到UNIX计算机并运行它时,没有余留的回送连接,并且没有用完它们的问题。

2

这是我对同一问题的反应问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){} 
} 

唯一的一次,你要使用一个循环,手动犯规关闭通道是当你有从用户交互的键盘输入。然后当用户做一个'退出',将改变频道的'getExitStatus'。如果你的循环是while(channel.getExitStatus()== -1),那么循环将在用户退出时退出。检测到退出状态后,您仍然需要自行断开通道和会话。

未在其示例页面上列出,但JSCH在其网站上托管交互式键盘演示。 http://www.jcraft.com/jsch/examples/UserAuthKI.java

即使他们的演示,我用来连接到AIX系统而不更改他们的任何代码......在退出shell时不会关闭!

我不得不添加以下代码得到它正确地退出我曾在我的远程会话中键入“退出”后:

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

在上面添加了我的代码 - 我没有完全遵循您的建议。我认为我故意关闭频道。我不关心等待其余的输入。我需要添加什么? –

+1

该会话仍可以在目标服务器上保留。在你的程序端关闭会话不一定会结束服务器上的会话。您需要使用exit命令显式退出服务器,然后等待退出状态更新到您的通道对象中。 – Damienknight

+0

会导致本地机器上的开环回连接吗? –