2013-04-02 10 views
6

Po zakończeniu poniższego kodu netstat -a|grep sftp pokazuje otwarte połączenie SFTP. Pojawia się również jako otwarte połączenie w JProfiler.Dlaczego połączenie SFTP nadal istnieje po zamknięciu kanału JSCH?

channel.isConnected() w wreszcie wydruków blokowych fałszywych. Jakieś pomysły na to, że połączenia nie są zamykane, ponieważ nie mam problemów?

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

Dodawanie openNewTLSftpChannel() poniżej:

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

Odpowiedz

14

Jeśli spojrzeć na jsch examples SFTP zobaczysz, jak sesja jest zakończona:

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

You zauważysz, że są dwie części połączenia i rozłączenia; obiekt sesji i obiekt kanału.

W moim kodzie używam obiektu Session do ustawienia informacji o moim uwierzytelnieniu, a obiektu Channel do wykonania potrzebnych komend sftp.

W swojej instancji tworzysz obiekt Session w swojej metodzie openNewSftpChannel, ale nigdy nie jest on zamknięty, dzięki czemu twoja sesja pozostaje żywa.

Aby uzyskać dalszy kontekst, sprawdź przykłady.

+0

Można mieć wiele kanałów wewnątrz jednej sesji (zarówno w tym samym czasie, jak i kolejno), więc jest to dobra rzecz, że sesja jest nie jest automatycznie zamykane, gdy jeden kanał jest zamknięty. –

+0

To nie jest prawdą - wyjście po prostu wywołuje rozłączenie. Nic więcej. –

+0

sftpChannel.exit() wywołuje metodę rozłączania za pośrednictwem klasy Channel, która jest dziedziczona przez program ChannelSftp (wiersz 494 z Channel.java), session.disconnect jest wywoływana za pomocą własnej metody rozłączania (wiersz 1545 Session.java). –

4

Robert H jest poprawny, musisz opuścić swój kanał i odłączyć sesję. Chciałem dodać, że sesja istnieje nawet wtedy, gdy kanał został zamknięty. Ponieważ twoja sesja została utworzona w bloku try wewnątrz metody, wygląda na to, że straciłeś sesję, ale możesz ją odzyskać za pomocą funkcji getSession na swoim kanale sftpChannel.

można zmienić w końcu zablokować do tego:

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