这几天在做一个FTP上传文件的功能,在本地运行完全没有问题,上传文件成功。在公网(centos系统)上进行测试的时候就出了问题了,上传一直卡到storeFile上,一般是会卡住30-60秒,然后返回“false”,不报异常。所以我又开始怀疑代码的问题,在本地建了个CentOS的虚拟机,安装vsftp,结果是成功的。使用FTP上传工具进行处理,公网上传下载一点问题都没有,不会出现0字节的问题,至此,我就十分无耐了,同样的代码,在不同环境上支行的效果居然不一样。
没办法,我只能想常规的想法一样,开始怀疑环境问题,按照说明,对公网的vsftp重新整了一遍,结果还是一样的,我去,什么鬼。
在百度搜到了千千万万的处理方法,一个的试,都没有处理好。其中有一个文章说到FTP的模式,VSFTP有两种模式:pasv模式与port模式,什么意思,不懂,再搜索一下。
Port模式:
当客户端C向服务端S连接后,使用的是Port模式,那么客户端C会发送一条命令告诉服务端S(客户端C在本地打开了一个端口N在等着你进行数据连接),当服务端S收到这个Port命令后 就会向客户端打开的那个端口N进行连接,这种数据连接就生成了。
Pasv模式:
当客户端C向服务端S连接后,服务端S会发信息给客户端C,这个信息是(服务端S在本地打开了一个端口M,你现在去连接我吧),当客户端C收到这个信息后,就可以向服务端S的M端口进行连接,连接成功后,数据连接也建立了。
从上面的解释中,大家可以看到两种模式主要的不同是数据连接建立的不同,对于Port模式,是客户端C在本地打开一个端口等服务端S去连接建立数据连接;而Pasv模式就是服务端S打开一个端口等待客户端C去建立一个数据连接。
默认情况下,FTPCLIENT用的是port模式,可以在FTPCLIENT原码中看到
private void__initDefaults(){
this.__dataConnectionMode = 0;
....
}
public voidenterLocalActiveMode() {
this.__dataConnectionMode = 0;
this.__passiveHost = null;
this.__passivePort = -1;
}
public voidenterLocalPassiveMode() {
this.__dataConnectionMode = 2;
this.__passiveHost = null;
this.__passivePort = -1;
} 不知道是不是这个问题,试一下吧,反正模式是客户端发起的,代码上加入ftpClient.enterLocalPassiveMode();
直接运行,成功。
附上ftp上传与下载代码:
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTPClient;
import java.io.*;
import java.util.logging.Logger;
/**
* 含义:ftp的上传下载处理对象
*/
public class FtpFileTransfer {
private FTPClient ftpClient = null;//ftp客户端对象
private static String hostname = null;//FTP主机名称
private static Integer port = 0;//FTP服务端口
private static String userName = null;//FTP服务器登录用户名
private static String passwd=null;/