13

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

channel.isConnected()finally块中打印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;
}
4

2 回答 2

25

如果您查看 SFTP 的 JSCH示例,您将看到会话是如何终止的:

//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 对象,但它永远不会关闭,因此您的会话保持活动状态。

有关更多上下文,请查看示例。

于 2013-04-02T19:03:51.177 回答
6

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

您可以将 finally 块更改为:

} finally {
    if (channel != null) {
        Session session = channel.getSession();
        channel.disconnect();
        session.disconnect();
        System.out.println(channel.isConnected());
    }
}
于 2013-04-02T21:00:54.483 回答