Apache FTPClient操作“卡死”问题的分析和解决

在生产环境中,使用Apache FTPClient进行FTP操作时遇到了不规律的“卡死”问题。尝试设置ConnectTimeout、DataTimeout、DefaultTimeout并未解决问题。进一步研究后发现,需切换到被动模式并配合超时设置才能解决在Linux环境下FTPClient调用listFiles()和retrieveFile()时的阻塞问题。通过修改为被动模式和设置超时,问题最终得到解决。
摘要由CSDN通过智能技术生成

       最近在和一个第三方的合作中不得已需要使用FTP文件接口。由于FTP Server由对方提供,而且双方背后各自的网络环境都很不单纯等等原因,造成测试环境无法模拟实际情况。测试环境中程序一切正常,但是在部署到生产环境之后发现FTP操作不规律性出现“卡死”现象:程序捕获不到任何异常一直卡着,导致轮巡无法正常工作。

     为了解决这个问题,我首先考虑的是对于FTPClient的使用上没有设置超时时间,于是设置了ConnectTimeout、DataTimeout、DefaultTimeout后在生产环境上继续观察,但是问题依旧没有解决。又经过一翻研究之后发现:需要使用被动模式,操作简单描述:
          在项目中使用commons-net-3.0.1.jar实现FTP文件的下载,在windows xp上运行正常,但是放到linux上,却出现问题,程序运行到 FTPClient.listFiles()或者FTPClient.retrieveFile()方法时,就停止在那里,什么反应都没有,出现假死状态。google一把,发现很多人也出现了此类问题,最终在一个帖子里找到了解决办法。在调用这两个方法之前,调用FTPClient.enterLocalPassiveMode();这个方法的意思就是每次数据连接之前,ftp client告诉ftp server开通一个端口来传输数据。为什么要这样做呢,因为ftp server可能每次开启不同的端口来传输数据,但是在linux上,由于安全限制,可能某些端口没有开启,所以就出现阻塞。OK,问题解决。

    于是我回滚了之前的修改,改为被动模式(关于FTP主动/被动模式的解释,这里我不多说了,关注的朋友可以自己查阅)。但是问题依旧。从FTPClient api本身去解决问题,进行尝试:既设置被动模式又设置超时时间。经过实际测试,发现问题得以解决。下面把我的FTP工具类贴给大家分享,希望能帮到遇到同样问题的人。

 

import org.apache.commons.net.ftp.FTP;
  2 import org.apache.commons.net.ftp.FTPClient;
  3 import org.apache.commons.net.ftp.FTPFile;
  4 import org.apache.commons.net.ftp.FTPReply;
  5 
  6 import java.io.BufferedInputStream;
  7 import java.io.BufferedOutputStream;
  8 import java.io.File;
  9 import java.io.FileInputStream;
 10 import java.io.FileNotFoundException;
 11 import java.io.FileOutputStream;
 12 import java.io.IOException;
 13 import java.io.InputStream;
 14 import java.io.OutputStream;
 15 import java.net.UnknownHostException;
 16 import java.util.ArrayList;
 17 import java.util.List;
 18 
 19 public class FtpUtil {
 20     public static final String ANONYMOUS_LOGIN = "anonymous";
 21     private FTPClient ftp;
 22     private boolean is_connected;
 23 
 24     public FtpUtil() {
 25         ftp = new FTPClient();
 26         is_connected = false;
 27     }
 28     
 29     public FtpUtil(int defaultTimeoutSecond, int connectTimeoutSecond, int dataTimeoutSecond){
 30         ftp = new FTPClient();
 31         is_connected = false;
 32         
 33         ftp.setDefaultTimeout(defaultTimeoutSecond * 1000);
 34         ftp.setConnectTimeout(connectTimeoutSecond * 1000);
 35         ftp.setDataTimeout(dataTimeoutSecond * 1000);
 36     }
 37 
 38     /**
 39      * Connects to FTP server.
 40      * 
 41      * @param host
 42      *            FTP server address or name
 43      * @param port
 44      *            FTP server port
 45      * @param user
 46      *            user name
 47      * @param password
 48      *            user password
 49      * @param isTextMode
 50      *            text / binary mode switch
 51      * @throws IOException
 52      *             on I/O errors
 53      */
 54     public void connect(String host, int port, String user, String password, boolean isTextMode) throws IOException {
 55         // Connect to server.
 56         try {
 57             ftp.connect(host, port);
 58         } catch (UnknownHostException ex) {
 59             throw new IOException("Can't find FTP server '" + host + "'");
 60         }
 61 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值