2014-10-16 21 views
0

我编程试图连接到远程的ssh上运行。我正在运行一个tomcat服务器实例。每当我需要从代码中创建一个会话,连接并执行try块中需要的几个命令,然后关闭在所有地方作为finally块的一部分创建的连接。事情做工精良细腻,但在某些情况下,当我的SSH服务器上执行W¯¯netstat的命令,我看到有空闲连接数超过几个小时,这些连接的IP地址显示连接来自我的应用程序,但我的Java堆转储不显示我的类在内存中的任何实例,但我在堆中看到ganymed相关的类实例。SSH连接离开失效会话服务器

我使用ganymed-SSH-260库连接到我的服务器。

这是不是有人已经见过?

附加的代码段connectes的SSH服务器

public class SSHExecutor{ 

private OutputStream stdin; 
private InputStream stdout; 
private InputStream stderr; 
private Session sess;  
private Connection conn;  

    public void createConnection(String hostname, int port, String userName, String password) throws Exception { 
     try { 
      conn = new Connection(hostname, port);   
      final boolean isAuthenticated = publicKeyAccess(hostname, userName, password); 
      if (!isAuthenticated) { 
       throw new IOException("Authentication failed."); 
      } 

      sess = conn.openSession(); 
      final int xWidth = 90; 
      final int yWidth = 80; 
      sess.requestPTY("dumb", xWidth, yWidth, 0, 0, null); 
      sess.startShell(); 
      stdin = sess.getStdin(); 
      stdout = sess.getStdout(); 
      stderr = sess.getStderr(); 

      isConnectionActive = true; 
      final String response = getResponse(); 
      if (response != null && response.toLowerCase().contains(ObjectConstants.CURRENTLY_NOT_AVAILABLE)) { 
       throw new IOException("Account is currently not available."); 
      } 
     } catch (Exception e) { 
      log.error("Problem in CreateConnection", e); 
      isConnectionActive = false;   
      throw e; 
     } 
    } 

    public String getResponse() { 
     final StringBuffer responseData = new StringBuffer(); 
     try { 
      final int byteValue = 8192; 
      final byte[] buffer = new byte[byteValue]; 
      try { 
       while (true) { 
        if ((stdout.available() == 0) && (stderr.available() == 0)) { 
         int conditions = 1; 
         if (promptString != null && promptString.length() > 0) { 
          final int fiveThousand = 5000; 
          conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA 
            | ChannelCondition.STDERR_DATA | ChannelCondition.EOF, fiveThousand); 
         } else { 
          conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA 
            | ChannelCondition.STDERR_DATA | ChannelCondition.EOF, 
            ObjectConstants.THOUSAND_FIVE_HUNDRED); 
         } 

         if ((conditions & ChannelCondition.TIMEOUT) != 0) { 
          break; 
         } 

         if ((conditions & ChannelCondition.EOF) != 0) { 
          if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0) { 
           break; 
          } 
         } 
        } 
        while (stdout.available() > 0) { 
         final int len = stdout.read(buffer); 
         if (len > 0) { 
          responseData.append(new String(buffer, 0, len)); 
         } 
        } 

        while (stderr.available() > 0) { 
         final int len = stderr.read(buffer); 
         if (len > 0) { 
          responseData.append(new String(buffer, 0, len)); 
         } 
        } 
        if (promptString != null && promptString.length() > 0) { 
         if (responseData.indexOf(promptString) != -1) { 
          break; 
         } 
        } 
       } 
      } catch (Exception e) { 
       log.error("Read Error :", e); 
      } 
     } catch (Exception e) { 
      log.error("getResponse Error ", e); 
     } 
     return responseData.toString(); 
    } 

    public String executeCommand(String command) throws IOException { 
     String response = null; 
     if (isConnectionActive && stdin != null) { 
      try { 
       stdin.write(command.getBytes()); 
       stdin.flush(); 
       response = getResponse(); 
      } catch (IOException ie) { 
       throw ie; 
      } catch (Exception e) { 
       log.error("Exception in executeCommandForPage()", e); 
       response = e.getMessage(); 
      } 
     } else { 
      response = "Connection not active."; 
     } 
     return response; 
    } 

    public void closeConnection() { 
     if (stderr != null) { 
      try { 
       stderr.close(); 
      } catch (Exception e) { 
       log.error("Exception in closeConnection()", e); 
      } 
     } 
     if (stdout != null) { 
      try { 
       stdout.close(); 
      } catch (Exception e) { 
       log.error("Exception in closeConnection()", e); 
      } 
     } 
     if (stdin != null) { 
      try { 
       stdin.close(); 
      } catch (Exception e) { 
       log.error("Exception in closeConnection()", e); 
      } 
     } 
     if (sess != null) { 
      try { 
       sess.close(); 
      } catch (Exception e) { 
       log.error("Exception in closeConnection()", e); 
      } 
     } 

     if (conn != null) { 
      try { 
       conn.close(); 
      } catch (Exception e) { 
       log.error("Exception in closeConnection()", e); 
      } 
     } 
    } 
} 

回答

0
  1. 你创建一个局部变量Connection但你要测试什么必须是一个成员变量,这始终是零,所以你永远不会关闭它。

  2. 如果认证失败你泄露的连接。

+0

真是抱歉。这是我尝试进行小规模调试时发生的错字。它实际上是一个全局连接对象,我在我的createConnection(..)方法中实例化..我更正了上面的代码。 – 2014-10-16 12:11:23