【所属类包】
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. GO第归

    Go 语言递归函数 递归,就是在运行的过程中调用自己. 语法格式如下: func recursion() {    recursion() /* 函数调用自身 */ } func main() {   ...

  2. 吴裕雄--天生自然Numpy库学习笔记:NumPy 位运算

    bitwise_and() 函数对数组中整数的二进制形式执行位与运算. import numpy as np print ('13 和 17 的二进制形式:') a,b = 13,17 print ( ...

  3. ➡️➡️➡️IELTS reading by Simon on Bili

    高分必备 雅思考官Simon手把手教你做阅读 p1 https://www.bilibili.com/video/av40131278?p=2 p2 https://www.bilibili.com/ ...

  4. win10 安装"pip install orange3" 出现LINK : fatal error LNK1158: cannot run 'rc.exe' 错误的解决办法

    解决办法: 从(本例使用的是64位的python3.6 注意:如果python的版本是32位,则使用x86:如果是64位,则使用x64;) 复制一下两个文件 rc.exe rcdll.dll 到

  5. 「国家集训队」middle

    「国家集训队」middle 传送门 按照中位数题的套路,二分答案 \(mid\),序列中 \(\ge mid\) 记为 \(1\),\(< mid\) 的记为 \(-1\) 然后只要存在一个区间 ...

  6. php cli 下 php.ini 配置

    // 查看phpcli 模式下 扩展 php -m // 查看php cli 版本 php -v 查看命令行的ini路径,命令行下运行 php --ini Loaded Configuration F ...

  7. UIControl的API

    @property(nonatomic, readonly) UIControlState state; 控件的状态,指定为位掩码值. @property(nonatomic, getter=isEn ...

  8. unity优化-内存(网上整理)

    内存优化内存的开销无外乎以下三大部分:1.资源内存占用:2.引擎模块自身内存占用:3.托管堆内存占用.在一个较为复杂的大中型项目中,资源的内存占用往往占据了总体内存的70%以上.因此,资源使用是否恰当 ...

  9. The 2019 ICPC China Nanchang National Invitational and International Silk-Road Programming Contest - F.Sequence(打表+线段树)

    题意:给你一个长度为$n$的数组,定义函数$f(l,r)=a_{l} \oplus a_{l+1} \oplus...\oplus a_{r}$,$F(l,r)=f(l,l)\oplus f(l,l+ ...

  10. Atcoder Beginner Contest 139E(模拟,思维)

    #define HAVE_STRUCT_TIMESPEC#include<bits/stdc++.h>using namespace std;int n;int a[1007][1007] ...