当前位置: 首页 > 知识库问答 >
问题:

使用FTP Apache传输文件的问题Java实现

姚培
2023-03-14

我正在使用FTP和JAVA传输文件。我正在使用Apache中的FTPClient和FTPServer。但在特定环境中,有时文件不会传输。在调用login方法之前,我从FTPClient调用enterLocalPassiveMode方法,但有时文件不会被传输。

  1. store File方法返回“false”。
  2. getReplyString方法返回“200命令类型可以”。
  3. list方法返回“227”。

文件传输成功时:

  1. list方法返回150

客户端代码:

        this.getFtpClientUtil().connect(settingsService.getServer(), settingsService.getFtpServerCommandChannelPort());

        int reply = this.getFtpClientUtil().getReplyCode();

        if (!FTPReply.isPositiveCompletion(reply)) {
            logger.error("Fail to connect to FTP Server");
            this.getFtpClientUtil().disconnect();
            isConnect = false;
            return false;
        }

        logger.info("FTP Server connected successfully");
        this.getFtpClientUtil().enterLocalPassiveMode();
        isConnect = this.getFtpClientUtil().login(settingsService.getftpUsername(), settingsService.getftpPassword());

服务器代码:

        // Data Configuration
        this.dataConfigurationFactory = new DataConnectionConfigurationFactory();
        dataConfigurationFactory.setPassiveAddress(this.ipAddress);
        dataConfigurationFactory.setPassiveExternalAddress(this.ipAddress);
        dataConfigurationFactory.setPassivePorts(this.settingsService.getFtpServerTransferChannelPort());

        // Listener
        listenerFactory = new ListenerFactory();
        listenerFactory.setPort(this.settingsService.getFtpServerCommandChannelPort());
        listenerFactory.setDataConnectionConfiguration(dataConfigurationFactory.createDataConnectionConfiguration());

        // Desliga SSL
        listenerFactory.setImplicitSsl(false);

        // User
        PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();
        UserManager um = userManagerFactory.createUserManager();

        this.serverFactory = new FtpServerFactory();
        serverFactory.addListener("default", listenerFactory.createListener());
        serverFactory.setUserManager(um);

        UserFactory userFactory = new UserFactory();
        userFactory.setName(this.settingsService.getftpUsername());
        userFactory.setPassword(this.settingsService.getftpPassword());
        userFactory.setMaxIdleTime(60);

        final String absolutePath = this.settingsService.getftpHomeDirectory();

        userFactory.setHomeDirectory(absolutePath);
        userFactory.setAuthorities(Arrays.asList((Authority) new WritePermission()));

        User user = userFactory.createUser();
        um.save(user);

        // Connection Config
        connectionConfigFactory = new ConnectionConfigFactory();
        connectionConfigFactory.setAnonymousLoginEnabled(false);
        connectionConfigFactory.setMaxLogins(100);
        serverFactory.setConnectionConfig(connectionConfigFactory.createConnectionConfig());

这是防火墙问题吗?

我尝试使用DataConnectionConfigurationFactory类中的setPassivePorts方法在服务器端设置被动端口范围,但问题仍在继续。

是否有任何形式可以在客户端设置端口范围?如何检查连接是否真正使用被动模式?

提前感谢。

共有1个答案

施敏达
2023-03-14

这是防火墙问题吗?

在这些情况下,正确的方法是关闭防火墙来测试或设置应用程序可以连接的端口范围。但是在正式生产环境中这不是一个选项。所以,我唯一知道的是在开发环境中工作正常,在正式生产环境中问题出现了。我的假设是防火墙正在阻止端口。

是否有任何形式可以在客户端设置端口范围?如何检查连接是否真正使用被动模式?

可以在FTPClient的connect()方法上设置本地端口:

this.getFtpClientUtil().connect(settingsService.getServer(), settingsService.getFtpServerCommandChannelPort(), 
                InetAddress.getLocalHost(), getLocalPort());

可以通过两种方式验证连接是否使用被动模式:

  1. 如果未使用被动模式,则来自FTPClient的getPassivePort()方法将返回-1
  2. 在这个问题中,我提到了FTPClient的list()方法返回227代码。该代码还表示正在使用被动模式。我认为这个代码是一个错误。真正发生的是在进入被动模式后出错,但返回的代码来自上一个命令

设置本地端口无法解决问题。可能是因为我正在配置的本地端口仅用于命令通道。传输通道仍然在客户端使用随机端口。解决方案是再次尝试传输文件。如果传输失败,我会断开客户端,然后使用其他端口再次连接客户端,然后再次尝试传输文件。在我所有的测试中,文件在第二次成功传输。如果传输失败,我会尝试3次。

再次连接客户端时,如果使用相同的端口,java可能抛出“java.net.BindException:地址已在使用”。即使在断开客户端连接后,端口仍会继续锁定几分钟。在这种情况下,我在尝试连接之前验证端口是否可用,如果必要,我尝试在另一个端口中连接客户端。

 类似资料:
  • 如何通过MAP-Reduce实现文件传输?为了实现这一点,我需要在映射器、还原器和作业的输入-输出中设置哪些参数?

  • 问题描述 我想将前端获取到的文件通过POST请求作为请求体参数传给后端,但是传过去之后发现文件是个空对象{} 问题出现的环境背景及自己尝试过哪些方法 问过chatgpt和查阅的一些资料后我尝试将File对象转化为Blob对象然后再传给后端,结果发现还是空对象{};之后我又尝试通过FormData来作为POST请求体参数可还是无济于事 相关代码 以下是nodejs后端对路由的统一处理:

  • 我正在寻找以下问题的答案。 > 在服务器断开的情况下,Camel SFPT是否支持resume功能。我注意到,一旦从基础JSCH库抛出SocketTimeout/IOException异常,就会删除.inprogress文件。我的期望是,一旦连接可用,camel应该重新建立连接,并从它离开的地方恢复下载。 connectTimeout、timeout和soTimeout等参数不起作用。在windo

  • FileZilla在尝试通过SFTP模式连接到AWS实例时抛出错误。实例运行在Ubuntu 13.10上。 连接参数:

  • 本文向大家介绍Java Socket实现文件传输示例代码,包括了Java Socket实现文件传输示例代码的使用技巧和注意事项,需要的朋友参考一下 最近学Socket学上瘾了,就写了一个简单的文件传输程序。 客户端设计思路:客户端与服务端建立连接,选择客户端本地文件,先将文件名及大小等属性发送给服务端,再将文件通过流的方式传输给服务端。传输的进度打印到控制台中,直到传输完成。 服务端设计思路:服务

  • 但是,当我第一次调用此路由时,即使指定了fileName参数,文件input1.txt也会被传输。请帮忙。