我正在尝试使用以下来自Android应用的代码将文件上传到FTP服务器
System.setProperty("jdk.tls.useExtendedMasterSecret", "false");
FTPSClient ftpClient = new SSLSessionReuseFTPSClient("TLS",
false);
ftpClient.addProtocolCommandListener(new PrintCommandListener(new
PrintWriter(System.out)));
KeyManagerFactory kmf =
KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(null, null);
KeyManager km = kmf.getKeyManagers()[0];
ftpClient.setKeyManager(km);
ftpClient.setBufferSize(1000);
ftpClient.setConnectTimeout(5000);
ftpClient.connect(InetAddress.getByName(host), port);
// ftpClient.setEnabledSessionCreation(false);
// Set protection buffer size
ftpClient.execPBSZ(0);
// // Set data channel protection to private
ftpClient.execPROT("P");
ftpClient.login(username, password);
//ftpClient.changeWorkingDirectory("/Data/");
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
ftpClient.enterLocalPassiveMode();
BufferedInputStream buffInp = new BufferedInputStream(new
FileInputStream(gpxFile.getAbsolutePath()));
//throwing exception here
boolean status = ftpClient.storeFile(remote, buffInp);
System.out.println("===>"+status);
但是它说“ 522 SSL连接失败;需要会话重用:请参见vsftpd.conf手册页android ftps中的require_ssl_reuse选项”
SSLSessionReuseFTPSClient.Java
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Locale;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import org.apache.commons.net.ftp.FTPSClient;
//import com.google.common.base.Throwables;
public class SSLSessionReuseFTPSClient extends FTPSClient {
// adapted from: https://trac.cyberduck.io/changeset/10760
@Override
protected void _prepareDataSocket_(final Socket socket) throws IOException {
if(socket instanceof SSLSocket) {
final SSLSession session = ((SSLSocket) _socket_).getSession();
final SSLSessionContext context = session.getSessionContext();
try {
final Field sessionHostPortCache =
context.getClass().getDeclaredField("sessionHostPortCache");
sessionHostPortCache.setAccessible(true);
final Object cache = sessionHostPortCache.get(context);
final Method putMethod = cache.getClass().getDeclaredMethod("put",
Object.class, Object.class);
putMethod.setAccessible(true);
final Method getHostMethod =
socket.getClass().getDeclaredMethod("getHost");
getHostMethod.setAccessible(true);
Object host = getHostMethod.invoke(socket);
final String key = String.format("%s:%s", host,
String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT);
putMethod.invoke(cache, key, session);
} catch(Exception e) {
//throw Throwables.propagate(e);
}
}
}
}
直到需要重新使用会话为止,请帮忙,谢谢。