2015-01-08 111 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

會導致本地機器上的開環回連接嗎? –