Search code examples
javaftpftps

FTPSClient raise an exception when trying to login() after logout()


I need to write code in Java which connects to the list of servers using FTP over SSL protocol and get some files from it. Every server has list of logins and passwords. I need to connect to server using every login in rotations. Something like this:

//  This is not a real code it's just a sketch of what I need to do.
for (Server server : servers) {
    server.connect();
    for (LoginPassword loginPassword : server.loginPasswordList) {
        server.login(loginPassword);
        server.getSomeFiles();
        server.logout();
    }
    server.disconnect();
}

I am using FTPSClient from apache commons:

ftpClient = ftpClient.connect("host", port);
int reply = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
    if (ftpClient.login("login", "password")) {
        ftpClient.execPBSZ(0);
        ftpClient.execPROT("P");
        ftpClient.enterLocalPassiveMode();

        System.out.println(ftpClient.logout()); //  true
    } 
    if (ftpClient.login("another_login", "another_password")) { //  this line raise an exception
        ftpClient.execPBSZ(0);
        ftpClient.execPROT("P");
        ftpClient.enterLocalPassiveMode();

        System.out.println(ftpClient.logout()); //  true
    }
}

This code fails when I am trying to logout and login once again to the same connection. I receive this exception:

org.apache.commons.net.ftp.FTPConnectionClosedException: Connection closed without indication.

But if I close connection (ftpClient.disconnect();) after logout and then open it once again (ftpClient.connect("host", port)) like in code below then it works fine.

ftpClient = ftpClient.connect("host", port);
int reply = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
    if (ftpClient.login("login", "password")) {
        ftpClient.execPBSZ(0);
        ftpClient.execPROT("P");
        ftpClient.enterLocalPassiveMode();

        System.out.println(ftpClient.logout()); //  true
    } 
}
ftpClien.disconnect();
ftpClient = ftpClient.connect("host", port);
int reply = ftpClient.getReplyCode();
if (FTPReply.isPositiveCompletion(reply)) {
    if (ftpClient.login("another_login", "another_password")) {//  this works fine
        ftpClient.execPBSZ(0);
        ftpClient.execPROT("P");
        ftpClient.enterLocalPassiveMode();

        System.out.println(ftpClient.logout()); //  true
    } 
}

Of course I can use this code, but the problem is that there is large list of servers and logins, and creation of new connection takes ~1 second, but ftpClient.login() takes only ~50 ms. So If I will use code with new connection for every login then it will take about 3150 ms for three logins to one server instead of 1150 ms. So what can be the reason why I can't login to servers after logout?


Solution

  • It isn't legal to issue any commands after a close. You should issue a reinitialize, if the client API provides it, and then the new login(); otherwise you could try just the new login() without the prior logout(). Whether a second login is permitted on the same connection is however server-dependent and is not required by RFC 959.