Question

I have an application that makes simulations.In the beginning of each simulation, FTP connection is created and after that some upload/download files operations are done. then simulation starts.After simulation finishes, again some upload file operations is required for back up simulation related folders

We encounter a problem if simulation takes more than 5 minutes.In the mean time, FTP connection is idle.I get following exceptions.

java.net.SocketException: Software caused connection abort: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92)
at java.net.SocketOutputStream.write(SocketOutputStream.java:136)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:276)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:122)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:212)
at java.io.BufferedWriter.flush(BufferedWriter.java:236)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:477)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:537)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:586)
at org.apache.commons.net.ftp.FTP.quit(FTP.java:794)
at org.apache.commons.net.ftp.FTPClient.logout(FTPClient.java:788)


Caused by: java.net.SocketException: Software caused connection abort: recv failed
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:129)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at org.apache.commons.net.ftp.FTP.__getReply(FTP.java:295)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:495)
at org.apache.commons.net.ftp.FTP.sendCommand(FTP.java:537)
at org.apache.commons.net.ftp.FTP.mkd(FTP.java:1363)
at org.apache.commons.net.ftp.FTPClient.makeDirectory(FTPClient.java:1971)

I tried following actions just after simulation is completed, I tried to reinitialize FTP , but no success.I see that connection is active in FTP side

1)FTPClient.isConnected() method returns true

2)When I call FTPClient.connect(), it throws exception FTP is already initialized

3)I tried to set timeouts in connect method of FTP.

public boolean connect() throws IllegalStateException, FileTransferException {
    /*
     * Precondition checks
     */
    final FTPClient clientBefore = this.getClient();
    if (clientBefore != null && clientBefore.isConnected()) {
        throw new IllegalStateException("FTP Client is already initialized");
    }
    // Create the client
    final FTPClient client = new FTPClient();
    client.setConnectTimeout(600000);
    client.setDefaultTimeout(600000);
    // FTPClientConfig conf = new FTPClientConfig(FTPClientConfig.SYST_NT);
    // client.configure(conf);
    log.trace("Connecting to FTP Server at " + config.getCanonicalForm());
    try {
        client.connect(config.getHost(), config.getPort());
        client.setSoTimeout(600000);
    } catch (final IOException ioe) {
        throw new FileTransferException("Error in connecting to " + config.getCanonicalForm(),
                ioe);
    }
    log.trace("Connected to FTP Server at: " + config.getCanonicalForm());
    this.setClient(client);
    // Check that the last operation succeeded
    this.checkLastOperation();
    boolean result;
    try {
        // Login
        if (client.login(config.getUserName(), config.getPassword())) {
            result = true;
            // If there's a pwd defined, cd into it.
            final String pwd = this.getPresentWorkingDirectory();
            if (pwd != null) {
                this.cd(pwd);
            }
        } else {
            result = false;
        }
    } catch (final Exception e) {
        throw new FileTransferException("Could not log in", e);
    }
    return result;
}

Now, I am on deadlock.I do not know what is the problem

Was it helpful?

Solution

If you really have to keep the connection alive, run NOOP commands against the server, so that the control connection remains alive.

Either do it manually:

client.sendNoOp();

Or set the client to do it at fixed interval rates:

client.setControlKeepAliveTimeout(300); // set timeout to 5 minutes

But if you can avoid wasting resources, logout and disconect after the initial download phase, do your local processing and connect / login again for uploading afterwards.

OTHER TIPS

Remember in addition to ftp timeout mentioned by others that any firewalls / NAT in the communication path may time out, in typically less than 5 minutes.

Dive into the source code.

When FTPClient make the control connection connect

client.connect(config.getHost(), config.getPort());

it use some code works like this:

Socket socket = SocketFactory.getDefault().createSocket();

to create a socket to connect to the ftp server.

If you can, set keepalive option to socket, using

socket.setKeepAlive(true);

Hierarchy:

├── SocketClient
│   ├── FTP
│   │   └── FTPClient
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top