ftpclient超时时间设置
使用apacher的commons-net-2.0.jar中的 org.apache.commons.net.ftp.FtpClient有一段时间了。然而程序时不时挂起,无任何反应。很是郁闷,于是详细看了一下它的源码,总算是把超时时间设置给搞定了。
ftpClient.setConnectTimeout(connectTimeOut);//设置 命令连接 超时时间
ftpClient.setDefaultTimeout(dataTimeOut);//设置 命令连接 数据超时时间
ftpClient.setSoTimeout(60*1000);//设置 主动模式下 数据超时时间
一直以为像上面这样设置就没问题了,可事实上并不是这样子,FtpClient并没有直接提供 被动模式下数据连接的连接超时和数据接收超时时间的接口。当然我们可以间接的实现它。需要用到这个方法:
ftpClient.setSocketFactory(factory);
当然我们要创建一个SocketFactory的实例,SocketFactory是一个虚类,我们需要继承一下,于是我写了个MySocketFactory:
public class MySocketFactory extends SocketFactory {
private int connectTimeOut = 120 * 1000;
private int dataTimeOut = 60 * 1000;
@Override
public Socket createSocket() throws IOException,
UnknownHostException {
Socket socket = new Socket();
socket.setSoTimeout(dataTimeOut);
return socket;
}
@Override
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
InetAddress address = InetAddress.getByName(host);
return createSocket(address, port, null, 0);
}
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
return createSocket(host, port, null, 0);
}
@Override
public Socket createSocket(String host, int port, InetAddress localHost,
int localPort) throws IOException, UnknownHostException {
InetAddress address = InetAddress.getByName(host);
return createSocket(address, port, localHost, localPort);
}
@Override
public Socket createSocket(InetAddress address, int port,
InetAddress localAddress, int localPort) throws IOException {
Socket socket = new Socket();
SocketAddress remote = new InetSocketAddress(address, port);
if (localAddress != null) {
SocketAddress local = new InetSocketAddress(localAddress, localPort);
socket.bind(local);
}
socket.connect(remote, connectTimeOut);
socket.setSoTimeout(dataTimeOut);
return socket;
}
}
所以为了让FtpClient的超时时间完全生效,我们需要这样写:
ftpClient = new FTPClient();
ftpClient.setConnectTimeout(connectTimeOut);
ftpClient.setDefaultTimeout(dataTimeOut);
ftpClient.setSoTimeout(60*1000);
MySocketFactory factory = new MySocketFactory();
ftpClient.setSocketFactory(factory);
还是相当的麻烦呀。希望下次apache可以修正这个问题