美文网首页程序员
FTP主动,被动模式----附代码

FTP主动,被动模式----附代码

作者: BlackChen | 来源:发表于2018-01-09 14:44 被阅读45次

    http://blog.csdn.net/wumenglu1018/article/details/54233826

    FTP的主动传输和被动传输

    主动模式:

    • 客户端从端口N向服务器21端口发起连接.
    • 客户端再N+1端口监听服务器的连接.
    • 服务器从端口20 向客户端 N+1 端口发起连接.


      image.png

    被动模式:

    • 客户端从端口N向服务器21端口发起连接.
    • 服务端在X端口(X>1024)监听客户端的连接.
    • 客户端从端口N+1 向服务端 X 端口发起连接.


      image.png

    主动FTP:
      命令连接:客户端 大于1024端口 -> 服务器 21端口
      数据连接:客户端 大于1024端口 <- 服务器20端口

    被动FTP:
      命令连接:客户端 大于1024端口 -> 服务器 21端口
      数据连接:客户端 大于1024端口 -> 服务器 大于1024端口

    简要总结:

    • 主动FTP对FTP服务器的管理有利,但对客户端的管理不利。因为FTP服务器企图与客户端的高位随机端口建立连接,而这个端口很有可能被客户端的防火墙阻塞掉。
    • 被动FTP对FTP客户端的管理有利,但对服务器端的管理不利。因为客户端要与服务器端建立两个连接,其中一个连到一个高位随机端口,而这个端口很有可能被服务器端的防火墙阻塞掉。

    办法:

    • 既然FTP服务器的管理员需要他们的服务器有最多的客户连接,那么必须得支持被动FTP。我们可以通过为FTP服务器指定一个有限的端口范围来减小服务器高位端口的暴露。这样,不在这个范围的任何端口会被服务器的防火墙阻塞。虽然这没有消除所有针对服务器的危险,但它大大减少了危险.

    例:
    Class FTPParam : FTP所需参数

    import lombok.Builder;
    
    /**
     * ftp配置属性
     */
    @Builder
    public class FTPParam {
        private String host;
        private int port;
        private String username;
        private String password;
        private String uploadPath;
        public String getHost() {
            return host;
        }
        public void setHost(String host) {
            this.host = host;
        }
        public int getPort() {
            return port;
        }
        public void setPort(int port) {
            this.port = port;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        public String getUploadPath() {
            return uploadPath;
        }
        public void setUploadPath(String uploadPath) {
            this.uploadPath = uploadPath;
        }
        /* (non-Javadoc)
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            StringBuilder builder = new StringBuilder();
            builder.append("FTPParam [host=");
            builder.append(host);
            builder.append(", port=");
            builder.append(port);
            builder.append(", username=");
            builder.append(username);
            builder.append(", password=");
            builder.append(password);
            builder.append(", uploadPath=");
            builder.append(uploadPath);
            builder.append("]");
            return builder.toString();
        }
        
        
    }
    

    Class FTPUtil: ftp工具类

    public class FTPUtil {
        public final static Logger LOG = LoggerFactory.getLogger(FTPUtil.class);
    
        /**
         * 发送文件到FTP
         *
         * @param fileLocalPath 本地文件路径(包含文件名 eg: //var//temp//test)
         * @param fileName 远程服务器文件名
         * @param param ftp配置
         * @return
         */
            public static boolean downLoadFileToLocal(String fileLocalPath, String fileName, FTPParam param) {
        LOG.info("开始下载文件至本地,param:{}",param);
            //状态
            boolean result = false;
            FTPClient ftpClient = new FTPClient();
            FileOutputStream fout = null;
            try {
                ftpClient.connect(param.getHost(), param.getPort());
                //判断ftp连接
                if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                    LOG.error("ftp connect fail,host:{}",param.getHost());
                    ftpClient.disconnect();
                    return result;
                }
                LOG.info("ftpClient.connect success.");
                //判断ftp登陆
                if(!ftpClient.login(param.getUsername(), param.getPassword())) {
                    LOG.error("ftp login fail,username:{}",param.getHost());
                    ftpClient.logout();
                    return result;
                }
                //设置文件类型 :二进制
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                //采用被动模式传输
                ftpClient.enterLocalPassiveMode();
                //设置路径
                LOG.info("ftpClient.connect 设置路径:{}",param.getUploadPath());
                boolean change = ftpClient.changeWorkingDirectory(param.getUploadPath());
                if(change){
                    fout = new FileOutputStream(fileLocalPath);
                    result = ftpClient.retrieveFile(fileName, fout);
                    LOG.info("---FTP下载完成---");
                }
                else {
                    LOG.info("ftpClient.connect 设置路径失败:{}", param.getUploadPath());
                }
            } catch (Exception e) {
                LOG.error("下载文件出错,报错:",e);
            } finally {
                try {
                    if(fout != null) {
                        fout.close();
                    }
                    if(ftpClient.isConnected()) {
                        ftpClient.logout();
                        ftpClient.disconnect();
                    }
                } catch (IOException e) {
                    LOG.error("关闭FTP或字节流出错,报错:",e);
                }
            }
            return result;
        }
        /**
         * 发送文件到FTP
         *
         * @param fileLocalPath 本地文件路径(包含文件名 eg: //var//temp//test) 
         * @param fileName 文件名(上传到远程服务器的文件名)
         * @param param ftp配置
         * @return
         */
        public static boolean upLoadFileToFTP(String fileLocalPath, String fileName, FTPParam param) {
            LOG.info("开始发送文件至FTP,param:{}",param);
            //状态
            boolean fal = false;
            FTPClient ftpClient = new FTPClient();
            FileInputStream fis = null;
            File file = null;
            try {
                ftpClient.connect(param.getHost(), param.getPort());
                //判断ftp连接
                if(!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                    LOG.error("ftp connect fail,host:{}",param.getHost());
                    ftpClient.disconnect();
                    return fal;
                }
                LOG.info("ftpClient.connect success.");
                //判断ftp登陆
                if(!ftpClient.login(param.getUsername(), param.getPassword())) {
                    LOG.error("ftp login fail,username:{}",param.getHost());
                    ftpClient.logout();
                    return fal;
                }
                //设置文件类型 :二进制
                ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
                file = new File(fileLocalPath);
                fis = new FileInputStream(file);
                //采用被动模式传输
                ftpClient.enterLocalPassiveMode();
                //设置上传路径
                boolean change = ftpClient.changeWorkingDirectory(param.getUploadPath());
                LOG.info("ftpClient.connect 设置上传路径:{}",param.getUploadPath());
                if(change) {
                    fal = ftpClient.storeFile(fileName, fis);
                    LOG.info("---FTP上传完成---");
                }else{
                     LOG.info("ftpClient.connect 设置上传路径失败:{}",param.getUploadPath());
                }
            } catch (Exception e) {
                LOG.error("上传FTP出错,报错:",e);
            } finally {
                try {
                    if(fis != null) {
                        fis.close();
                    }
                    fis = null;
                    file = null;
                    if(ftpClient.isConnected()) {
                        ftpClient.logout();
                        ftpClient.disconnect();
                    }
                } catch (IOException e) {
                    LOG.error("关闭FTP或字节流出错,报错:",e);
                }
            }
            return fal;
        }
    

    相关文章

      网友评论

        本文标题:FTP主动,被动模式----附代码

        本文链接:https://www.haomeiwen.com/subject/hrownxtx.html