java – 使用FTPS将文件从android传输到服务器

我在我的 Android应用程序中使用 Apache Commons FTP library

我通过FTPS建立连接,虽然它与服务器完美连接,但在传输文件时遇到问题.

出于安全原因,订购应用程序的客户端在使用PROT P时请求在数据连接上恢复TLS会话.

因此,我在服务器上启用了此选项:

正如我所说,我可以连接到服务器,但不能传输文件.
如果我取消激活“使用PROT P时数据连接上所需的TLS会话恢复”框,则传输正常.

我正在寻找一种使用库进行文件传输的方法,但是没有成功,但我知道必须有办法.

我给你相关代码的一部分:

TransferImagenesFTP.ftpClient = new FTPSClient();

TransferImagenesFTP.ftpClient.connect(InetAddress.getByName("XXX_XXX_XX_X"),26);
TransferImagenesFTP.ftpClient.enterLocalPassiveMode();
TransferImagenesFTP.ftpClient.setBufferSize(1024000);
TransferImagenesFTP.ftpClient.login("xxxxxx","zzzzzz");
TransferImagenesFTP.ftpClient.execPROT("P");
TransferImagenesFTP.ftpClient.type(FTP.BINARY_FILE_TYPE);

我感谢任何帮助,谢谢.

解决方法

您可以尝试以下代码,我希望它也适用于您的情况.

代码使用Apache Commons vsf2通过安全ftp连接(SFTP)上传文件

try {
  String filepath = "<FILE PATH>";
  String serverAddress = "<FTP SERVER ADDRESS>";
  String userId = "<FTP USER ID>";
  String password = "<FTP PASSWORD>";
  String remoteDirectory = "<FTP DIRECTORY TO UPLOAD TO>";   
  String keyPath = "<PATH TO YOUR KEY>";   
  String passphrase = "<PASSWORD FOR YOUR KEY>";   


  File file = new File(filepath);
  if (!file.exists())
    throw new RuntimeException("Error. File not found");

  //Initializes the file manager
  StandardFileSystemManager manager = new StandardFileSystemManager();
  manager.init();

  //Setup our SFTP configuration
  FileSystemOptions opts = new FileSystemOptions();
  SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts,"no");
  SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts,true);
  SftpFileSystemConfigBuilder.getInstance().setTimeout(opts,10000);

  // Create local file object
  FileObject localFile = manager.resolveFile(file.getAbsolutePath());

  // Create remote file object
  FileObject remoteFile = manager.resolveFile(createConnectionString(serverAddress,userId,password,keyPath,passphrase,filetoFTP),createDefaultOptions(keyPath,passphrase));


  // copy local file to sftp server
  remoteFile.copyFrom(localFile,Selectors.SELECT_SELF);
  System.out.println("File upload successful");

}
catch (Exception ex) {
  ex.printstacktrace();
  return false;
}
finally {
  manager.close();
}

您可以在Apache Commons VFS Documentation查看更多信息

编辑

在理解了FTPS背后的逻辑和@ riyaz-ali的帖子并将您的评论中的链接引用到this article之后

Apache FTP客户端存在问题,它不支持TLS会话恢复.您可以修补Apache Commons Library的现有实现.

您可以尝试以下代码步骤来使其工作:

>在项目中添加以下修补的类. (此类扩展了Apache commons中给出的补丁中现有的FTPS实现)

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 PatchedFTPSClient extends FTPSClient {

        @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 method = cache.getClass().getDeclaredMethod("put",Object.class,Object.class);
                                method.setAccessible(true);
                                final String key = String.format("%s:%s",socket.getInetAddress().getHostName(),String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT);
                                method.invoke(cache,key,session);
                        } catch(Exception e) {
                                throw Throwables.propagate(e);
                        }
                }
        }

}

>使用此修改后的代码段.

TransferImagenesFTP.ftpClient = new PatchedFTPSClient();

TransferImagenesFTP.ftpClient.connect(InetAddress.getByName<SERVER-ADDRESS>"),26);
TransferImagenesFTP.ftpClient.login("<USERNAME>","<PASSWORD>");
TransferImagenesFTP.ftpClient.execPBSZ(0);
TransferImagenesFTP.ftpClient.execPROT("P");
TransferImagenesFTP.ftpClient.enterLocalPassiveMode();

//Now use the FTP client to upload the file as usual.

希望这对您有用,并将解决您的问题.

相关文章

Android 通过adb shell命令查看内存,CPU,启动时间,电量等...
Monkey Android app稳定性测试工具之Monkey使用教程 by:授客...
Android 常见adb命令 by:授客 QQ:1033553122 1、 查看所有已...
这篇“android轻量级无侵入式管理数据库自动升级组件怎么实现...
今天小编给大家分享一下Android实现自定义圆形进度条的常用方...
这篇文章主要讲解了“Android如何解决字符对齐问题”,文中的...