2013-04-02 272 views
6

當下面的代碼運行完畢時,netstat -a|grep sftp顯示一個打開的SFTP連接。它也顯示爲JProfiler中的一個開放連接。爲什麼JSCH通道關閉後SFTP連接仍然存在?

channel.isConnected()最後版畫。任何想法爲什麼連接不會因爲我處於虧損而關閉?

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; 
} 

回答

14

如果你看一看的JSCH examples爲SFTP你會看到會話終止如何:

//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對象設置我的認證信息,和海峽對象執行我所需要的SFTP命令。

在您的實例,你創建你的openNewSftpChannel方法Session對象,但它永遠不會關閉,因此您的會話保持活着。

欲瞭解更多信息,請查看示例。

+0

人們可以有一個會話內多種渠道(無論是在同一時間,以及順序),因此它是一件好事,本次會議是一個通道關閉時不會自動關閉。 –

+0

這是不正確的 - 退出只是斷開連接。沒有其他的。 –

+0

sftpChannel.exit()通過ChannelSftp繼承的Channel類(Channel.java的494行)調用disconnect方法,通過自己的disconnect方法(Session.java的1545行)調用session.disconnect。 –

4

Robert H是正確的,您需要退出您的頻道並斷開您的會話。我想補充一點,即使通道已關閉,會話仍然存在。由於您在方法內的try塊內創建了會話,因此您的會話似乎已經丟失,但是您可以使用sftpChannel通道上的'getSession'將其恢復。

你可以改變你的finally塊來此:

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