FTPClient 上传文件连接超时java.net.ConnectException: Connection timed out: connect

今天用nginx+vsftpd做了一个图片服务器,使用Java代码上传和下载图片的过程中上传失败,reply也不返回值
Ubuntu16下的nginx+vsftpd的配置见另一个博客

上传类的代码

    /**
     * Description: 向FTP服务器上传文件
     * @param host FTP服务器hostname
     * @param port FTP服务器端口
     * @param username FTP登录账号
     * @param password FTP登录密码
     * @param basePath FTP服务器基础目录
     * @param filePath FTP服务器文件存放路径。例如分日期存放:/2019/01/01。文件的路径为basePath+filePath
     * @param filename 上传到FTP服务器上的文件名
     * @param input 输入流
     * @return 成功返回true,否则返回false
     */
    public static boolean uploadFile(String host, int port, String username, String password, String basePath, String filePath, String filename, InputStream input){
        boolean result = false;
        FTPClient ftp = new FTPClient();
        FTPClientConfig config = new FTPClientConfig();
        config.setLenientFutureDates(true);
        ftp.configure(config);
        try{
            int reply;
            ftp.connect(host, port);    //连接FTP服务器
            //如果采用默认端口,则可以使用connect(host)的方式直接连接ftp服务器
            ftp.login(username, password);      //登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)){
                ftp.disconnect();
                return result;
            }
            //切换到上传目录
            if (!ftp.changeWorkingDirectory(basePath+filePath)){
                    //如果目录不存在则创建目录
                    String[] dirs = filePath.split("/");
                    String tempPath = basePath;
                for (String dir : dirs){
                    if (null == dir || "".equals(dir)) continue;
                    tempPath += "/" + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)){
                        if (!ftp.makeDirectory(tempPath)){
                            return result;
                        }else {
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            //设置文件上传类型为二进制类型
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            //上传文件
            if (!ftp.storeFile(filename, input)){
                return result;
            }
            System.out.println(result);
            input.close();
            ftp.logout();
            result = true;
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if (ftp.isConnected()){
                try{
                    ftp.disconnect();
                }catch (IOException ioe){
                    ioe.printStackTrace();
                }
            }
        }

        return result;
    }

但是运行结果显示我已经成功上传,但是我的服务器上没有任何数据

解决思路

google了许多大佬们的博客,大致都是在说vsftpd的工作模式有两种
FTPClient 上传文件连接超时java.net.ConnectException: Connection timed out: connect_第1张图片
于是我添加了如下代码

ftp.enterLocalPassiveMode();		//这个设置允许被动连接--访问远程ftp时需要

但是又出了问题

java.net.ConnectException: Connection timed out: connect
	at java.net.DualStackPlainSocketImpl.connect0(Native Method)
	at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
	at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
	at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
	at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
	at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
	at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
	at java.net.Socket.connect(Socket.java:589)
	at org.apache.commons.net.ftp.FTPClient._openDataConnection_(FTPClient.java:894)
	at org.apache.commons.net.ftp.FTPClient._storeFile(FTPClient.java:633)
	at org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:624)
	at org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:1976)
	at main.cn.sico_technology.simon.FtpUtil.uploadFile(FtpUtil.java:58)
	at main.cn.sico_technology.simon.FTPTest.testFtpUtils(FTPTest.java:38)
	at main.cn.sico_technology.simon.FTPTest.main(FTPTest.java:50)

显示我 ftp连接超时,试图通过printf debug法检查我的程序到底运行到哪里出了问题,显示在目录的创建上就进不去了。

理解PASV(被动模式)的工作流程

FTPClient 上传文件连接超时java.net.ConnectException: Connection timed out: connect_第2张图片
于是我更换了允许被动连接的代码的位置在ftp.connect();之前

	    FTPClient ftp = new FTPClient();
        ftp.enterLocalPassiveMode();        //这个设置允许被动连接--访问远程ftp时需要
        FTPClientConfig config = new FTPClientConfig();
        config.setLenientFutureDates(true);
        ftp.configure(config);

再次运行则可以正常上传下载
FTPClient 上传文件连接超时java.net.ConnectException: Connection timed out: connect_第3张图片
服务器端数据
FTPClient 上传文件连接超时java.net.ConnectException: Connection timed out: connect_第4张图片

你可能感兴趣的:(Java,APache,FTPClient,ftp,nginx,vsftpd)