apache ftpclient 能login不能做其它操作的问题记录

这两天一直在为一个FTP上传文件的项目纠结

以前的员工用sun.net.ftp.FtpClient写了一个上传文件项目,经常出现小问题,公司要求优化,并将

sun.net.ftp.FtpClient 改成apache的FtpClient

代码修改以后apache FtpClient 能够登陆,

   ftp.login(user, pass) 成功

   但是其它操作ftp.listNames(),storeFile 一执行就报错

   java.net.SocketException: Connection reset

开始我以为是  主被动模式问题

   当前用的jdk1.6版本 这个版本的sun.net.ftp.FtpClient只有被动模式

   我确认我的代码中有加入 ftp.enterLocalActiveMode();

   我尝试换成主动模式试了,肯定还是不行,服务器根本不会主动连接我的ftp客户端

   (对方服务器配置的就是被动模式)

再次分析问题,

      1.sun.net.ftp.FtpClient可以连接并上传文件

      2.apache的FtpClient 可以login成功

      3.异常报错指向apache的FtpClient   PASV()这个方法

      4.我尝试直接使用ftp协议pasv 立刻就提示 java.net.SocketException: Connection reset

难道sun.net.ftp.FtpClient没有运行PASV指令  ? 

于是我查看了sun.net.ftp.FtpClient源码,果然其中有一段

         

if (issueCommand("EPSV ALL") == FTP_SUCCESS)
    {
      if (issueCommand("EPSV") == FTP_ERROR){
     
      ....

} else {
      if (issueCommand("PASV") == FTP_ERROR)

 它先执行的是EPSV ALL

回过头来查询apacheClient  源码 

 boolean attemptEPSV = (isUseEPSVwithIPv4()) || (isInet6Address);
      if ((attemptEPSV) && (epsv() == 229))
      {
        __parseExtendedPassiveModeReply((String)this._replyLines.get(0));
      }
      else
      {
        if (isInet6Address) {
          return null;
        }

        if (pasv() != 227) {
          return null;
        }

 原来如此

     修改代码加上ftp.setUseEPSVwithIPv4(true);

 终于文件上传成功了.

注意 我用的是  commons-net-3.0.jar 

为什么PASV不能执行,继续找ing....

   

  

猜你喜欢

转载自yxjajl.iteye.com/blog/2336905