FTPS连接在Android中引发错误

时间:2018-07-18 14:55:46

标签: android ftps

我正在尝试使用以下来自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);
      }
    }
  }
}

直到需要重新使用会话为止,请帮忙,谢谢。

0 个答案:

没有答案