【所属类包】
org.apache.commons.net.ftp.FTPClient
【现象描述】
这两天java项目中用到了FTP下载,像之前的项目写好代码,但是点击下载后,程序调试到下面这一行,就没反应了。
InputStream ins = ftpClient.retrieveFileStream(filePath);
没反应还不打紧,再次点击下载,代码都根本不会走到这个方法了,除非重启服务,调试的无比蛋疼。
 
本以为是文件夹定位错误,就想看看到底能不能拿到目录下的文件列表
FTPFile[] fs = ftpClient.listFiles();
结果,程序走到这一段就又没消息了。。。
 
【解决办法】
调用 FTPClient.listFiles()或者FTPClient.retrieveFile()方法前,先调用一下FTPClient.enterLocalPassiveMode()
 
【测试范例】
示例1:
ftpClient.enterLocalPassiveMode();
FTPFile[] fs = ftpClient.listFiles();

示例2:

ftpClient.enterLocalPassiveMode();
InputStream ins = ftpClient.retrieveFileStream(remotefilePath);

示例3:

ftpClient.enterLocalPassiveMode();
InputStream ins = ftpClient.retrieveFile(remotefilePath, outputStream);

【原因分析】Last updated on 2018/07/19

FTP有两种模式:主动模式(active mode)和被动模式(passive mode)
默认情况下是启动的主动模式。
 
FTP是TCP链接,所以在读取文件时,要进行三次握手。
我这里在进行调试的时候,FTP Server的防火墙是关闭的,但是服务器Tomcat是在我本地PC跑的,防火墙是开启的,即FTP Client开防火墙了。
当FTP使用主动模式时,在三次握手后,FTP Client会开启一个>1024的端口,FTP Server会开启默认端口20,并主动向FTP Client发起数据连接请求。
而此时受我电脑防火墙的限制,FTP Server获得FTP Client的数据端口后,会主动发起数据连接请求,此时会被防火墙被屏蔽的。
FTP Client无法正常接收FTP Server发送来的数据流,所以就会出现假死的现象。
 
如果强制FTP使用被动模式,三次握手完成后,FTP Client会开启一个>1024的端口,并要求FTP Server开启一个端口(>1024),被动等待数据通道链接的开启。
当FTP Client开启数据传输通道时,FTP Server就开始被动传输数据,不存在被墙住的问题,文件就可以正常下载下来了。
 
主动模式(active mode)和被动模式(passive mode)的更多介绍,可参见以下博客:
 
【问题扩展】
如果你的程序在自己电脑上可以正常下载FTP文件,但是上线后确不可以了,下载文件假死,请核查是不是生产环境服务器的防火墙没有关闭。
如果有特殊原因,生产环境服务器防火墙要开着,那建议在写Java代码读取文件时,用上FTPClient.enterLocalPassiveMode()。
 

FTPClient下载文件,程序假死问题的更多相关文章

  1. Delphi IdHTTP1下载文件防止假死 (

    在Form1中添加控件:两个Indy控件:IdAntiFreeze1,IdHTTP1;一个按钮 :Button1;一个进度条 :ProgressBar1 显示下载速度 procedure TForm1 ...

  2. 解决ArcEngine开发程序“假死”现象

    在GIS数据处理中,数据量大是一个非常伤脑筋的问题.最近,在写一个CAD注记转Shapefile文件时,又遇到这个问题. 曾经处理一次数据,达130万个点,即测试区域内的栅格转成点全部处理,程序是写好 ...

  3. 解决因为终端打印造成的java程序假死

    问题状态: java 程序 日志采用 log4j 运行时由另一个管理进程拉起,程序在后台运行. 现象: 程序后台运行时,运行一段时间后假死 分析原因: 尝试打印输出,定位假死的具体位置,发现出现假死的 ...

  4. 实现winfrom进度条及进度信息提示,winfrom程序假死处理

    1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线程,如果不采用多线程控制进度条,窗口 ...

  5. [转] 实现winfrom进度条及进度信息提示,winfrom程序假死处理

    china_xuhua 原文地址 1.方法一:使用线程 功能描述:在用c#做WinFrom开发的过程中.我们经常需要用到进度条(ProgressBar)用于显示进度信息.这时候我们可能就需要用到多线 ...

  6. java线程基础巩固---多Product多Consumer之间的通讯导致出现程序假死的原因分析

    在上一次中已经实现一个生产者与消费者的初步模型(http://www.cnblogs.com/webor2006/p/8413286.html),但是当时只是一个生产者对应一个消费者,先贴下代码: p ...

  7. linux 下定位程序假死

    ps -ef | grep 程序名称 pstack 程序的进程ID

  8. JVM定位程序假死或cpu占用高的线程

    linux系统: 参考:https://blog.csdn.net/qq_40197576/article/details/80287515 1>使用top命令查看占用cpu进程情况,得到jav ...

  9. 发现用System.Net.Mail发邮件(代码附后),附件稍微大一点就会造成程序假死. 有没有什么简单的解决办法呢? 多谢!!

    附件大,上传,发送一定会慢.程序卡,应该是主线程正在发送,邮件造成的.创建其他线程在后台去发.这样就不影响主线程做其他工作了   using System; using System.Collecti ...

随机推荐

  1. .NET中的字符串(5):字符串驻留

    StringBuilder对象 通过上面的分析可以看出,String类型在做字符串的连接操作时,效率是相当低的,并且由于每做一个连接操作,都会在内存中创建一个新的对象,占用了大量的内存空间.这样就引出 ...

  2. 如何判断WLC的FUS版本

    有些时候,我们在升级WLC的时候,被告知需要升级WLC的FUS,以防止某些漏洞和不必要的情况发生. 1.什么是FUS? Field Upgrade Software (FUS),翻译过来,叫“现场升级 ...

  3. cookie按钮点击倒计时

    <!--引入jquery.cookie.js 插件--> <script src="js/jquery.js" type="text/javascrip ...

  4. Meaven搭建springboot项目

    1.创建一个简单的maven project项目 2.项目目录结构 **注意启动类的位置: 3.pom.xml 配置jar包 <parent> <groupId>org.spr ...

  5. 十四、制作优美的div弹框

    功能描述:确认[调整按钮]弹出精美div弹框 1.jsp页面:perfectAlertDiv.jsp <%@ page contentType="text/html;charset=U ...

  6. openjudge 和为给定数(二分答案)

    嗯... 题目链接:http://noi.openjudge.cn/ch0111/07/ 这道题是一道不太明显,但很好二分的二分答案的一道题... 首先排序(二分要满足单调性),然后枚举每一个数,在[ ...

  7. [原]greenplum安装详细过程

    今天又帮其他项目装了一遍GP,加上之前的两次,这是第三次了,虽然每次都有记录,但这次安装还是发现漏写了一些步骤,在此详细记录一下,需要的童鞋可以借鉴. 1.准备 这里准备了4台服务器,1台做maste ...

  8. CSS的响应式布局

    响应式布局是什么 它是相对于固定像素大小的网页而言的,顾名思义,响应式布局就是网页能够响应各种各样不同分辨率大小的设备,能够将网页很好的呈献给用户. 如何实现响应式布局? 1.CSS3@media查询 ...

  9. Java的进制转换

    十进制转其它进制 其它进制转十进制 A进制转B进制可以将十进制作为中间媒介 Integer.toString(int i, int radix) 返回用第二个参数指定基数表示的第一个参数的字符串表示形 ...

  10. javascript对象创建及继承

    //****************************************************************************** //创建类的多种方式 //------ ...