Apache commons net FTP客户端无法预测地挂起

时间:2018-01-29 03:51:42

标签: apache-commons-net

我们尝试了这篇文章(FTP client hangs)中提供的所有解决方案,但它们都没有奏效。我们正在使用版本3.6的公共网络。有时它会在上传文件时挂起,有时会检查目录是否存在。最大。文件大小约为400 MB。但有时即使是小文件大小,它也会挂起。 1KB。下面是代码片段:

        public boolean uploadData(String inputFilePath, String destinationFolderName) {
                    if (StringUtil.isNullOrBlank(inputFilePath) || StringUtil.isNullOrBlank(destinationFolderName)) {
                        LOGGER.error("Invalid parameters to uploadData. Aborting...");
                        return false;
                    }
                    boolean result = false;
                    FTPSClient ftpClient = getFTPSClient();
                    if (ftpClient == null) {
                        logFTPConnectionError();
                        return false;
                    }
                     try {
                        loginToFTPServer(ftpClient);
                        result = uploadFileToFTPServer(ftpClient, inputFilePath, destinationFolderName);
                    } catch (Exception e) {
                        logErrorUploadingFile(inputFilePath, e);
                        return false;
                    } finally {
                        try {
                            logoutFromFTPServer(ftpClient);
                        } catch (Exception e) {
                            logErrorUploadingFile(inputFilePath, e);
                            result = false;
                        }
                    }
                    return result;
                }

    private FTPSClient getFTPSClient() {
            FTPSClient ftpClient = null;
            try {
                ftpClient = new FTPSClient();
                LOGGER.debug("Connecting to FTP server...");
                ftpClient.setConnectTimeout(connectTimeOut);
                ftpClient.connect(server);
                int reply = ftpClient.getReplyCode();
                if (!FTPReply.isPositiveCompletion(reply)) {
                    ftpClient.disconnect();
                    LOGGER.error("Could not connect to FTP server. Aborting.");
                    return null;
                }
            } catch (Exception e) {
                LOGGER.error("Could not connect to FTP server.", e);
                return null;
            }
            return ftpClient;
        }

    private void loginToFTPServer(FTPSClient ftpClient) throws Exception {
            ftpClient.setDataTimeout(DATA_TIMEOUT);
            ftpClient.login(ftpUserName, ftpPassword);
            ftpClient.enterLocalPassiveMode();
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
            LOGGER.debug("FTP Client Buffer Size Before:" + ftpClient.getBufferSize());
            ftpClient.setBufferSize(BUFFER_SIZE);
            LOGGER.debug("FTP Client Buffer Size After:" + ftpClient.getBufferSize());
            ftpClient.execPBSZ(0);
            ftpClient.execPROT("P");
            ftpClient.setControlKeepAliveTimeout(300);
            LOGGER.debug("Logged into FTP server.");
        }

    private void logoutFromFTPServer(FTPSClient ftpClient) throws Exception {
            LOGGER.debug("Logging out from FTP server.");
            ftpClient.logout();
            ftpClient.disconnect();
            LOGGER.debug("FTP server connection closed.");
        }

private boolean uploadFileToFTPServer(FTPSClient ftpClient, String inputFilePath, String destinationFolderName) {
        boolean result = false;
        String remoteLocationFile;
        File ftpFile = new File(inputFilePath);
        try (InputStream inputStream = new FileInputStream(ftpFile)) {
            String fileName = ftpFile.getName();
            remoteLocationFile = (destinationFolderName == null || destinationFolderName.isEmpty())
                    ? ftpFile.getName()
                    : destinationFolderName + File.separator + fileName;
            LOGGER.info("Storing file " + ftpFile.getName() + " of size "
                    + ftpFile.length() + " in folder " + remoteLocationFile);
            result = ftpClient.storeFile(remoteLocationFile, inputStream);
            if(result) {
                LOGGER.info("Successfully stored file " + ftpFile.getName() + " in folder " + remoteLocationFile);
            } else {
                LOGGER.error("Unable to store file " + ftpFile.getName() + " in folder " + remoteLocationFile);
            }
            return result;
        } catch (Exception e) {
            logErrorUploadingFile(inputFilePath, e);
        }
        return result;
    }

应用程序托管在apache tomcat 8.这个问题的其他原因是什么?我们应该如何修复它们?这是我们应用程序的关键功能,如果稳定,我们甚至可以考虑使用备用API。请建议。

2 个答案:

答案 0 :(得分:0)

添加ftpClient.setSoTimeout(20000);已经解决了这个问题。

答案 1 :(得分:0)

enterLocalPassiveMode之前添加retreiveFile应该可以解决此问题。

您还需要添加

ftpClient.setControlKeepAliveTimeout(300);

Check this code which will resolve the hanging issue