SSH连接在服务器上留下陈旧的会话

时间:2014-10-16 10:58:24

标签: java ssh

我正在以编程方式尝试连接到远程运行的ssh。我正在运行一个tomcat服务器实例。每当我需要时,从代码中,我创建一个会话,连接并执行try块中需要的一些命令,然后关闭在所有位置作为finally块的一部分创建的连接。事情很好,但在某些情况下,当我在ssh服务器上执行 w netstat 命令时,我看到一些空闲的连接超过几个小时和这些连接的IP地址显示连接来自我的应用程序,但我的java堆转储没有在内存中显示我的类的任何实例,但我在堆中看到了ganymed相关的类实例。

我正在使用ganymed-ssh-260库连接到我的服务器。

这是某人已经看过的东西吗?

附加将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);
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

  1. 您正在创建一个本地Connection变量,但您正在测试必须是成员变量的内容,该变量始终为null,因此您永远不会将其关闭。

  2. 如果身份验证失败,则会泄露连接。