最近因为项目需要,研究有关ftp的相关东西。结果发现一个问题。同样的程序在不同的机器上运行,结果有一个直接导致线程挂起,另外一个运行却正常。经过反复的测试最后发现,线程挂起的那台机器装有防火墙,导致调用retrieveFileStream方法时直接线程挂起。

经过网上一大堆的查找终于找到解决方法:

ftpClient.enterLocalPassiveMode(); 
设置FTPClient为被动传输模式即可解决线程挂起问题。此代码设置在登陆之后或者之前都可以。

参考代码如下:

 
  
  1. /**  
  2.  * <p>方法描述: [登陆FTP]</p>  
  3.  *  
  4.  * @return 登陆后的客户端类  
  5.  */ 
  6. public static FTPClient openFTP() {  
  7.     logger.info("--CANBUS服务-->基本工具类-->登陆FTP");  
  8.  
  9.     FTPClient ftpClient = new FTPClient();  
  10.  
  11.     try {  
  12.         ftpClient.connect(ftp.ip,ftp.port)));  
  13.         ftpClient.setControlEncoding("UTF-8");  
  14.         ftpClient.login(ftp.username,  
  15.                 ftp.password);  
  16.  
  17.         return ftpClient;  
  18.     } catch (Exception e) {  
  19.         System.out.println("登陆FTP失败!");  
  20.  
  21.         return null;  
  22.     }  

 注:用FTPClient部署在Linux上出现下载的文件小于FTP服务器实际文件的问题解决方法是加上一下一句代码:

 
  
  1. // 设置以二进制形式传输
  2. ftpClient.setFileType(FTP.BINARY_FILE_TYPE); 

最后给大家分享个好的文章:

FTP中的两种工作方式 
 
下面的文章介绍了FTP的两种模式和在实际工作中的一些注意事项和使用技巧,希望对大家有所帮助,并和大家一起来探讨、交流。 
FTP是一种文件传输协议,它支持两种模式,一种方式叫做Standard (也就是 Active,主动方式),一种是 Passive (也就是PASV,被动方式)。 Standard模式 FTP的客户端发送 PORT 命令到FTP server。Passive模式FTP的客户端发送 PASV命令到 FTP Server。 
下面介绍一个这两种方式的工作原理: 
Standard模式FTP 客户端首先和FTP Server的TCP 21端口建立连接,通过这个通道发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。 PORT命令包含了客户端用什么端口接收数据。在传送数据的时候,服务器端通过自己的TCP 20端口发送数据。  
 
FTP server必须和客户端建立一个新的连接用来传送数据。 
Passive模式在建立控制通道的时候和Standard模式类似,当客户端通过这个通道发送PASV 命令的时候,FTP server打开一个位于1024和5000之间的随机端口并且通知客户端在这个端口上传送数据的请求,然后FTP server 将通过这个端口进行数据的传送,这个时候FTP server不再需要建立一个新的和客户端之间的连接。  
现在的FTP软件里面包括在IE5以上的版本里面也已经支持这两种模式了。一般一些FTP客户端的软件就比较好设置了,一般都有一个PASV的选项,比如CuteFTP,传输的方式都有Standard和PASV的选项,可以自己进行选择;另外在IE里面如果要设置成PASV模式的话可以选中工具-Internet选项-高级-为FTP站点启用文件夹视图,否则就采用Standard模式。 
很多防火墙在设置的时候都是不允许接受外部发起的连接的,所以FTP的Standard模式在许多时候在内部网络的机器通过防火墙出去的时候受到了限制,因为从服务器的TCP 20无法和内部网络的客户端建立一个新的连接,造成无法工作。当然也可以设置成功,首先要创建一条规则就是允许内部的IP连接外部的IP的21端口;第二条就是禁止外部IP的TCP 20端口连接内部IP的<1024的端口,这条是为了防止外部连接内部的常规端口;第三条验证ACK是否等于1,这个的原理就参见TCP建立连接的三次握手吧。所以如果安全的配置的话非常困难,这个时候就想起来了PASV模式,因为不用建立新的连接,所以也就不会涉及到后面的问题了。但是管理员可能不想使用PASV模式,因为这个时候FTP Server会开放一个随机的高端口,尽管在IIS4和IIS5里面端口的范围是1024-5000,但是许多 FTP Server的端口范围达到了1024-65535,这个时候在这个主动开放的随机端口上是有完全的访问权限的,如果IIS也要设置成开放的端口为1024-65535,具体方法如下: 
1. regedt32 
2. 找到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters  
3. 编辑-添加-数值 
value Name: MaxUserPort Data Type: REG_DWORD value: 65534  
所以如果遇到了有防火墙的话或者怕配置麻烦的话还是采用PASV模式比较好些,但是如果真的对安全的需求很高的话建议采用Standard模式。