Java FTPClient(apache commons)storefile()成功上传文件,然后超时..?

以下是我必须将文件上传到FTP服务器的一些代码:

private boolean ftpSend(byte[] fileBytes, String filename, HashMap<String, String> endpointAddressData) throws Exception {
    boolean success = false;

    String login = endpointAddressData.get("user");
    String hostname = endpointAddressData.get("host");
    String password = endpointAddressData.get("password");

    String portString = endpointAddressData.get("port");
    int port = (portString == null) ? 21 : Integer.parseInt(portString);

    FTPClient ftpClient = new FTPClient();
    ByteArrayInputStream inputStream = null;
    try {
        ftpClient.setConnectTimeout(10000);
        ftpClient.connect(hostname, port);

        int reply = ftpClient.getReplyCode();

        if(!FTPReply.isPositiveCompletion(reply)) {
            ftpClient.disconnect();

            throw new Exception("FTP server " + hostname + " refused connection.");
        }

        if (password != null) {
            ftpClient.login(login, password);
        } else {
            ftpClient.user(login);
        }

        logger_.debug("FTP - Writing: " + ftpClient.printWorkingDirectory() + "/" + filename + " on host " + endpointAddressData.get("host"));

        inputStream = new ByteArrayInputStream(fileBytes);
        success = ftpClient.storeFile(filename, inputStream);
        inputStream.close();
        success = success && ftpClient.completePendingCommand();

        logger_.debug("FTP - Completed: " + ftpClient.printWorkingDirectory() + "/" + filename + " on host " + endpointAddressData.get("host"));

        ftpClient.disconnect();

    } catch (Exception ex) {
        success = false;

        logger_.error("An error occurred during FTP upload to " + endpointAddressData.get("host") + ".", ex);
    } finally {
        if (ftpClient.isConnected()) {
            ftpClient.abort();
            ftpClient.disconnect();
        }

        if (inputStream != null) {
            inputStream.close();
        }

        return success;
    }
}

当我使用一些测试数据运行它时,上传显然成功完成(这是FTP服务器日志):

(000009)01/05/2014 12:13:09 PM - (not logged in) (127.0.0.1)> USER ######
(000009)01/05/2014 12:13:09 PM - (not logged in) (127.0.0.1)> 331 Password required for ######
(000009)01/05/2014 12:13:09 PM - (not logged in) (127.0.0.1)> PASS ########
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 230 Logged on
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> PWD ########
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 257 "/" is current directory.
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> PORT 127,0,0,1,250,242
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 200 Port command successful
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> STOR testFTP1.txt
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 150 Opening data channel for file upload to server of "/testFTP1.txt"
(000009)01/05/2014 12:13:09 PM - anonymous (127.0.0.1)> 226 Successfully transferred "/testFTP1.txt"
(000009)01/05/2014 12:15:10 PM - anonymous (127.0.0.1)> 421 Connection timed out.
(000009)01/05/2014 12:15:10 PM - anonymous (127.0.0.1)> disconnected.

我究竟做错了什么?

最佳答案 在调试器中单步执行后,我发现ftpClient.completePendingCommand()调用导致超时.我猜这个命令已经完成,它正无限期地等待下一个命令.我评论说该行和代码很容易完成.

来自FTPClient上的JavaDoc:http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html#completePendingCommand()

There are a few FTPClient methods that do not complete the entire sequence of FTP commands to complete a transaction. These commands require some action by the programmer after the reception of a positive intermediate command. After the programmer’s code completes its actions, it must call this method to receive the completion reply from the server and verify the success of the entire transaction.

我猜storeFile()(FTP STOR命令)不是那些方法之一.

点赞