5分钟无效后,FTP不起作用

时间:2013-07-21 14:21:50

标签: java ftp-client apache-commons-net

我有一个进行模拟的应用程序。在每次模拟开始时,创建FTP连接,然后完成一些上传/下载文件操作。 然后模拟开始。模拟完成后,备份模拟相关文件夹

再次需要一些上传文件操作

如果模拟时间超过5分钟,我们会遇到问题。同时,FTP连接处于空闲状态。我遇到以下例外情况。

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)

我在模拟完成后尝试了以下操作,我尝试重新初始化FTP,但没有成功。我看到FTP连接处于活动状态

1)FTPClient.isConnected()方法返回true

2)当我调用FTPClient.connect()时,它会抛出异常FTP已初始化

3)我尝试在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;
}

现在,我陷入僵局。我不知道问题是什么

3 个答案:

答案 0 :(得分:3)

如果你真的必须保持连接存活,请对服务器运行NOOP commands,以便控制连接保持活动状态。

手动执行:

client.sendNoOp();

或者设置客户端以固定的间隔速率执行此操作:

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

但是,如果您可以避免在初始下载阶段后浪费资源logoutdisconect,请执行本地处理,然后再次connect / login进行上传。< / p>

答案 1 :(得分:1)

请记住,除了其他人提到的ftp超时,通信路径中的任何防火墙/ NAT都可能超时,通常不到5分钟。

答案 2 :(得分:0)

深入了解源代码。

当FTPClient进行控制连接连接时

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

它使用了一些像这样的代码:

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

创建一个连接到ftp服务器的套接字。

如果可以,请使用

为套接字设置keepalive选项
socket.setKeepAlive(true);

层次:

├── SocketClient
│   ├── FTP
│   │   └── FTPClient