2013-04-02 26 views
6

Quando il codice sottostante è terminato, netstat -a|grep sftp mostra una connessione SFTP aperta. Si presenta anche come una connessione aperta in JProfiler.Perché esiste ancora una connessione SFTP dopo che il canale JSCH è stato chiuso?

channel.isConnected() nelle stampe infine blocco falsi. Qualche idea sul perché le connessioni non vengano chiuse perché sono in perdita?

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

Aggiunta openNewTLSftpChannel() di seguito:

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

risposta

14

Se si dà un'occhiata al JSch examples per SFTP vedrete come la sessione viene terminata:

//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(); 

È noteremo che ci sono due parti per la connessione e la disconnessione; l'oggetto Session e l'oggetto Channel.

Nel mio codice utilizzo l'oggetto Session per impostare le mie informazioni di autenticazione e l'oggetto Channel per eseguire i comandi sftp di cui ho bisogno.

Nella tua istanza, stai creando l'oggetto Session nel tuo metodo openNewSftpChannel, ma non viene mai chiuso, quindi la tua sessione rimane attiva.

Per ulteriori informazioni, consultare gli esempi.

+0

si può avere più canali all'interno di una sessione (entrambi allo stesso tempo, così come in sequenza), quindi è una buona cosa che la sessione è non chiuso automaticamente quando un canale è chiuso. –

+0

Questo non è vero - esci solo chiamate disconnessione. Nient'altro. –

+0

sftpChannel.exit() chiama il metodo di disconnessione tramite la classe Channel, che ChannelSftp eredita (riga 494 di Channel.java), session.disconnect viene invocato tramite il proprio metodo di disconnessione (riga 1545 di Session.java). –

4

Robert H è corretto, è necessario uscire dal canale e disconnettere la sessione. Volevo aggiungere che la sessione esiste anche quando il canale è stato chiuso. Poiché crei la tua sessione all'interno di un blocco try all'interno di un metodo, sembra che tu abbia perso la tua sessione, ma puoi recuperarla usando 'getSession' sul tuo canale sftpChannel.

È possibile modificare la blocco finally a questo:

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