apache.commons.net.ftp 上传下载大文件时出现 FTPClient retrieveFile 假死(卡死)解决办法(3.5/3.6/3.7)

转载请注明出处:原博文传送门

1. 问题

使用 commons.net 包下载小文件时程序能够顺利完成,但在下载大文件时程序会将文件下载完毕(检查文件大小,跟需要下载的文件大小一直),但是一直卡在 FTPClient.retrieveFile 方法。在网上查找了很多原因,大概了解了问题的所在。

多大算大文件? 跟你的网速和服务器的网速有关系,其实不是大小问题,是跟数据传输时间有关系,具体原因请看下面。

2. 原因

FTPClient 连接时会产生两个 socket 连接,一个用来传输命令,一个用来传输数据。
当我们在上传和下载大文件时,只有传输数据的socket连接在活动,那么传输命令的socket长时间没有命令,就会被关闭,当我们文件下载或上传完毕后,FTPClient 调用 命令socket 就会一直等待,造成了上面说的问题。

3. 解决办法

  • 设置 FTPClient 每隔多少秒发送一次心跳信息

ftpClient.setControlKeepAliveTimeout(60); // 60s发送一次

    /**
     * Set the time to wait between sending control connection keepalive messages
     * when processing file upload or download.
     *
     * @param controlIdle the wait (in secs) between keepalive messages. Zero (or less) disables.
     * @since 3.0
     * @see #setControlKeepAliveReplyTimeout(int)
     */
    public void setControlKeepAliveTimeout(long controlIdle){
        __controlKeepAliveTimeout = controlIdle * 1000;
    }

我的配置信息

FTPClient ftpClient = new FTPClient();
ftpClient.setDefaultTimeout(3000);//设置默认超时时间
ftpClient.setConnectTimeout(3000);//设置连接超时时间
ftpClient.setDataTimeout(3000);//设置读取数据超时时间(每次socket传输,不是指整个下载)
ftpClient.setControlKeepAliveTimeout(60); // 设置ftp在上传或下载大文件时,保持ftp的control的socket连接keepalive
ftpClient.setControlEncoding("utf-8");//设置ftp字符集
ftpClient.enterLocalPassiveMode();//设置被动模式,文件传输端口设置
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值