JSCH通道关闭后,为什么SFTP连接仍然存在?

时间:2013-04-02 15:49:16

标签: java sftp jsch

当下面的代码运行完毕后,netstat -a|grep sftp显示一个打开的SFTP连接。它也显示为JProfiler中的开放连接。

finally 块中的

channel.isConnected()打印 false 。有什么想法为什么连接没有被关闭,因为我不知所措?

public static void clean() {
    com.jcraft.jsch.ChannelSftp channel = null;
    try {
        channel = Helper.openNewTLSftpChannel();
        channel.connect();
        channel.cd(remoteFileDirectory);

        List<ChannelSftp.LsEntry> list = channel.ls("*." + fileType);
        for (ChannelSftp.LsEntry file : list) {
            String fileName = file.getFilename();
            DateTime fileDate = new DateTime(parseDateFromFileName(fileName));

            //if this file is older than the cutoff date, delete from the SFTP share
            if (fileDate.compareTo(cleanupCutoffdate) < 0) {
                channel.rm(fileName);
            }
        }
    } catch (Exception exception) {
        exception.printStackTrace();
    } finally {
        if (channel != null) {
            channel.disconnect();
            System.out.println(channel.isConnected());
        }
    }
}

在下面添加openNewTLSftpChannel()

public static ChannelSftp openNewSftpChannel(String privateKeyFileName, String password, String username, String host, int port)
        throws ConfigurationErrorException {

    JSch jsch = new JSch();
    File sftpPrivateFile = new File(privateKeyFileName);
    Channel channel;
    try {
        if (!sftpPrivateFile.canRead()) {
            throw new ConfigurationErrorException("File access error: " + sftpPrivateFile.getAbsolutePath());
        }
        jsch.addIdentity(sftpPrivateFile.getAbsolutePath(), password);
        Session session = jsch.getSession(username, host, port);
        java.util.Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        session.connect();
        channel = session.openChannel("sftp");
    } catch (JSchException jschException) {
        throw new ConfigurationErrorException("File access error: " + sftpPrivateFile.getAbsolutePath());
    }
    return (ChannelSftp) channel;
}

2 个答案:

答案 0 :(得分:20)

如果您查看SFTP的JSCH examples,您将看到会话终止的方式:

//setup Session here 
...
session.connect();
...


Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;

...run sftp logic...

//close sessions here
sftpChannel.exit();
session.disconnect();

您会注意到连接和断开有两个部分; Session对象和Channel对象。

在我的代码中,我使用Session对象设置我的身份验证信息,并使用Channel对象来执行我需要的sftp命令。

在您的实例中,您在openNewSftpChannel方法中创建了Session对象,但它永远不会关闭,因此您的会话保持活动状态。

有关更多背景信息,请查看示例。

答案 1 :(得分:5)

Robert H是正确的,您需要退出频道并断开会话连接。我想补充一点,即使频道已经关闭,会话仍然存在。由于您在方法内的try块中创建会话,似乎您丢失了会话,但您可以使用sftpChannel频道上的“getSession”将其恢复。

您可以将finally块更改为:

} finally {
    if (channel != null) {
        Session session = channel.getSession();
        channel.disconnect();
        session.disconnect();
        System.out.println(channel.isConnected());
    }
}