Hello

Im using org.apache.commons.net's FTP object to make FTP transfers. The problem is that when the IP is down (example, the PC is turned off) a exception saying "No route to host" pops up and not only delays my program but gives a nasty error. How can I avoid this?

Thank you

Dani AI

Generated

Short summary: the delay you see is almost certainly the TCP connect/read timeouts (OS/Java level), not the println itself. The commons‑net FTPClient inherits socket timeout controls from SocketClient, so set an explicit connect timeout before calling connect() and avoid brittle string comparisons on exception messages — catch the specific network exceptions instead. As and suggested, add quick debug prints around connect(), the catch, and the start of finally to confirm where the pause happens. (commons.apache.org)

Practical fixes to apply (minimal changes): set a connect timeout and a data timeout, and enable the control-channel keepalive for long transfers. Example (commons‑net 3.x):

FTPClient client = new FTPClient();
client.setConnectTimeout(5000);                 // limit TCP connect to 5s
client.setDataTimeout(30000);                   // limit data-socket reads to 30s
client.setControlKeepAliveTimeout(Duration.ofSeconds(60)); // keep control channel alive during long store/retrieve
client.connect(host);

Check your commons‑net javadoc for the exact overloads for your library version (some older releases use int/long rather than java.time.Duration). These methods are provided by SocketClient/FTPClient; using them prevents long OS-level waits. (commons.apache.org)

Other robustness tips: catch the specific exceptions (java.net.ConnectException, SocketTimeoutException, NoRouteToHostException) instead of comparing e.getMessage(); keep disconnect()/close() calls inside their own small try/catch so cleanup can’t hang the caller; and if you must support an ancient commons‑net that lacks timeouts, run the connect in a dedicated worker thread or use an ExecutorService + Future.get(timeout, ...) and then close the socket on timeout. Finally, log only the concise message you need (don’t print full stack traces for expected network failures) so the program can quietly continue.

Recommended Answers

All 12 Replies

try - catch statements. but how are you expecting to proceed if the server is down?

try - catch statements. but how are you expecting to proceed if the server is down?

:S The answer is pretty obvious: Dont send.

I already use try-catch statements:

public  void ftpupload(String ip, String user, String pass, String file, String dir)
    {

        FTPClient client = new FTPClient();
        FileInputStream fis = null;
        try 
        {
            client.connect(ip);
            client.login(user, pass);
            try 
            {
                client.setFileType(FTP.BINARY_FILE_TYPE);
            } 
            catch (IOException e1) 
            {
                System.out.println("ERROR: Cannot change type of file( " +e1.getLocalizedMessage()+" )");
            }
            String filename = file;
            fis = new FileInputStream(filename);    

            boolean exists=client.changeWorkingDirectory(dir);
            if (exists==false)
            {
                client.makeDirectory(dir);
                client.storeFile(filename, fis);
                client.rename(filename, dir + filename);
            }
            else
            {
                client.storeFile(filename, fis);
                client.rename(filename, dir + filename);
            }
            client.logout();

        } 
        catch (IOException e) 
        {
            if (e.getLocalizedMessage().equals("Connection refused")==true)
            {
                System.out.println("Tried to connect but it refused connection. The IP is " + ip + " Check configuration and permissions.");
            }
            else
            {
                System.out.println("ERROR: A error has occured ( " +e.getLocalizedMessage()+" )");
            }


        }
        finally
        {
            try
            {
                if (fis!=null)
                {
                    fis.close();
                }
                if (client.isConnected()==true)
                {
                    client.disconnect();
                }

            }
            catch (IOException e) 
            {
                System.out.println("ERROR: A error has ocurred when trying to close the file ( " +e.getLocalizedMessage()+" )");
            }
        }
    }

It fails (if the ip cannot be reached) and it executes the System.out.println("ERROR: A error has occured ( " +e.getLocalizedMessage()+" )"); line. I would need to display that and simply continue on. Nothing else.

continue on with what? I assume the problem is you are continuing on, but you're just not going to the code you want to continue in.
three ways I think that can help you solve that:
1. put more code in your try block. you can put all the code about the connection, preparing the file, the sending, .... in there, since you already know that if the server can not be reached, there's no point in running that code.
2. in your catch block, throw a new exception that is caught after the code that you should skip (nested try-catch statements)
3. set a flag (boolean) default to false, and to true at the end of your try block. have whether you run the rest of that code depend on that flag. if the end of the try block is not reached, the vallue will be false and that code will not be executed.

        System.print.out("Hello");
        FTPClient client = new FTPClient();
        FileInputStream fis = null;
        try 
        {
            client.connect(ip);
            client.login(user, pass);
            try 
            {
                client.setFileType(FTP.BINARY_FILE_TYPE);
            } 
            catch (IOException e1) 
            {
                System.out.println("ERROR: Cannot change type of file( " +e1.getLocalizedMessage()+" )");
            }
            String filename = file;
            fis = new FileInputStream(filename);    

            boolean exists=client.changeWorkingDirectory(dir);
            if (exists==false)
            {
                client.makeDirectory(dir);
                client.storeFile(filename, fis);
                client.rename(filename, dir + filename);
            }
            else
            {
                client.storeFile(filename, fis);
                client.rename(filename, dir + filename);
            }
            client.logout();

        } 
        catch (IOException e) 
        {
            if (e.getLocalizedMessage().equals("Connection refused")==true)
            {
                System.out.println("Tried to connect but it refused connection. The IP is " + ip + " Check configuration and permissions.");
            }
            else
            {
                System.out.println("ERROR: A error has occured ( " +e.getLocalizedMessage()+" )"); //LINE 42
            }


        }
        finally
        {
            try
            {
                if (fis!=null)
                {
                    fis.close();
                }
                if (client.isConnected()==true)
                {
                    client.disconnect();
                }

            }
            catch (IOException e) 
            {
                System.out.println("ERROR: A error has ocurred when trying to close the file ( " +e.getLocalizedMessage()+" )");
            }
        }
        //Line 42 is printed out then the following:
        System.print.out("Bye");

I put the code without it being in a function as it is the same thing. Line 42 is printed then the following is but there is a long delay between. I dont want that delay to exist.

One small point:
if ((some boolean expression) == true)
is horribly redundant. It's sufficient, and clearer, just to say
if (some boolean expression)

One small point:
if ((some boolean expression) == true)
is horribly redundant. It's sufficient, and clearer, just to say
if (some boolean expression)

Im not going to get angry at that comment or anything but it has NOTHING to do with the topic at hand: Everyone writes code however they like.

OK, no offense was intended, just a small hint to help you write better code. Please just ignore it if you wish.
J

OK, no offense was intended, just a small hint to help you write better code. Please just ignore it if you wish.
J

I know and I know what you said is the exact same thing I put, I just consider it disrespectful to say that how a code is written is incorrect (in the sense of syntaxis, not logic of course). Everyone writes their code their own way. Just like the bracket debate of

if (something==something) { System.out.println("speak"); }

//VS

if (something==something){
System.out.println("speak");
}

//VS

if (something==something)
{
System.out.println("speak");
}

All the same thing just different writing styles.

you've forgotten

if ( something==something )
  System.out.println("speak");

as for your statement that everyone writes the code the way they want ... maybe up until they get a job as developer. then they'll write the code the way their employer/guidelines tell them to.

writing

if ( some boolean expression )

instead of

if ((some boolean expression) == true)

is not just because it is shorter, but because every human,no matter how good he/she is, is flawed. the difference between

if ((some boolean expression) == true)

and

if ((some boolean expression) != true)

is just one typo. one that can't occur when you use the short version.

as for your problem: add a printline as first line in the finally block. maybe it's in there that the 'delay' occurs.

Hello Im using org.apache.commons.net's FTP object to make FTP transfers. The problem is that when the IP is down (example,

alliemarsh, unles it is related to the question in this thread, please start a new Thread, so we don't get confused between the questions/situations.

Try to check where the delay is from by adding some println in various places, especially in your finally clause. Try to pin point where exactly is the cause and you should be able to handle that easier.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.