FTP服务简介与java实现ftp上传下载

FTP简介

FTP(File Transfer Protocol)是因特网中使用最广泛的文件传输协议。FTP协议是应用层协议,它是基于TCP协议的。FTP是一个客户/服务器系统。

FTP的两种传输模式(主动模式和被动模式)

关于主动还是被动都是针对于FTP服务器来说的,是选择主动模式还是被动模式是由客户端决定的。

主动模式

ftp主动模式过程大致如下:

1、客户端随机选取一个大于1024的非特权端口与FTP服务器的21号端口进行控制连接,由于FTP是基于TCP的,这个过程要经历三次握手。连接成功后,以后客户端与服务器之间的控制命令如上传、下载、切换路径等命令都是通过控制连接来传输的。

2、当需要进行数据连接且客户端选择发起的是主动模式的连接时,客户端会随机选择一个端口portB,通过命令通道发送到FTP服务器,并等待FTP服务器主动发起FTP数据连接。

3、FTP服务器收到了客户端的请求,并主动通过20号端口向客户端的portB发起数据连接,这个过程也是有三次握手的。

这样在客户机与FTP服务器就建立了两个连接,一个控制连接用于传输命令,一个数据连接用于传输数据。

ftp连接在客户端没有发起数据请求时是不会马上建立数据连接的。FTP上控制连接端口号是21,数据连接端口号是20

被动模式

被动模式解析:

1、建立控制连接、同主动模式。

2、当需要数据连接时,客户端向ftp服务器发起被动模式请求,等待服务器的回应。

3、服务器接收到请求并开启一个监听的端口号pasvPortftp服务器通过命令通过告知客户机自己的被动连接端口pasvPort,等待客户端发起连接。

4、客户机向随机选取一个portBftp服务器的pasvPort端口发起数据连接

可以看到被动模式的FTP数据连接是由客户机主动发起的。

在Java项目中如何使用FTP服务

1、使用的是FTPClient,需要在maven中添加依赖:
<dependency>
	<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
    <version>1.4.1</version>
</dependency>
2、新建了一个FTPUtil工具类,用来管理FTP的连接、上传和下载。
public class FtpUtil {
	public static final String ftpHost = "111.231.250.43";
	public static final String ftpUserName = "lcl";
	public static final String ftpPassword = "123";
	public static final int ftpPort = 21;
	public static final String ftpPath = "appdata/service/";
	public static final String ftpPathClient = "appdata/client/";
	public static final String uploadPath = System.getProperty("user.dir");
	/**
     * 获取FTPClient对象
     *
     * @param ftpHost     FTP主机服务器
     * @param ftpPassword FTP 登录密码
     * @param ftpUserName FTP登录用户名
     * @param ftpPort     FTP端口 默认为21
     * @return
     */
    public static FTPClient getFTPClient(String ftpHost, String ftpUserName,
                                         String ftpPassword, int ftpPort) {
        FTPClient ftpClient = new FTPClient();
        try {
            ftpClient = new FTPClient();
            ftpClient.connect(ftpHost, ftpPort);// 连接FTP服务器
            ftpClient.login(ftpUserName, ftpPassword);// 登陆FTP服务器
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                System.out.println("未连接到FTP,用户名或密码错误。");
                ftpClient.disconnect();
                return null;
            } else {
                System.out.println("FTP连接成功。");
            }
        } catch (SocketException e) {
            e.printStackTrace();
            System.out.println("FTP的IP地址可能错误,请正确配置。");
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("FTP的端口错误,请正确配置。");
            return null;
        }
        return ftpClient;
    }

    /*
     * 从FTP服务器下载文件
     *
     * @param ftpHost FTP IP地址
     * @param ftpUserName FTP 用户名
     * @param ftpPassword FTP用户名密码
     * @param ftpPort FTP端口
     * @param ftpPath FTP服务器中文件所在路径 格式: appdata/service/年月/
     * @param localPath 下载到本地的位置 格式:xx/upload/
     * @param fileName 文件名称  如 app_20180803.zip
     */
    public static boolean downloadFtpFile(String ftpHost, String ftpUserName,
    		String ftpPassword, int ftpPort, String ftpPath, String localPath,String fileName) {
        FTPClient ftpClient = null;
        try {
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            if(ftpClient == null){
            	//ftp连接不上返回false
            	return false;
            }
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            //客户机进入ftp的被动模式,主动向FTP服务器发起数据连接
            ftpClient.enterLocalPassiveMode();
            //切换到服务器的指定路径下
            ftpClient.changeWorkingDirectory(ftpPath);
            //创建要下载的文件
            File localFile = new File(localPath+fileName);
            if(!localFile.exists()){
            	localFile.createNewFile();
            }
            OutputStream os = new FileOutputStream(localFile);
            //retrieveFile方法将当前路径下名为fileName的文件放到os输出流中,即进行文件下载
            boolean flag = ftpClient.retrieveFile(fileName, os);
            os.flush();
            os.close();
            ftpClient.logout();
            if(!flag){
            	return false;
            }
            return true;

        } catch (FileNotFoundException e) {
            System.out.println("没有找到" + ftpPath + "文件");
            e.printStackTrace();
            return false;
        } catch (SocketException e) {
            System.out.println("连接FTP失败.");
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("文件读取错误。");
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Description: 向FTP服务器上传文件
     * @param ftpHost FTP服务器hostname
     * @param ftpUserName 账号
     * @param ftpPassword 密码
     * @param ftpPort 端口
     * @param ftpPath  FTP服务器中文件所在路径 格式: appdata/client/
     * @param fileName ftp文件名称
     * @param input 文件流
     * @return 成功返回true,否则返回false
     */
    public static boolean uploadFile(String ftpHost, String ftpUserName,
                                     String ftpPassword, int ftpPort, String ftpPath,
                                     String fileName,InputStream input) {
        boolean success = false;
        FTPClient ftpClient = null;
        try {
            int reply;
            ftpClient = getFTPClient(ftpHost, ftpUserName, ftpPassword, ftpPort);
            reply = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                return success;
            }
            ftpClient.setControlEncoding("UTF-8"); // 中文支持
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftpClient.enterLocalPassiveMode();
            ftpClient.changeWorkingDirectory(ftpPath);
            String dirName = DateHelper.getYearAndMonth();
            //向服务器上查询文件是否存在,若不存在则创建文件
            ftpClient.makeDirectory(dirName);
            //切换到创建的文件夹下
            ftpClient.changeWorkingDirectory(dirName);
            //在ftp服务器上新建一个叫fileName发文件,并将input输入流中的内容写入fileName
            ftpClient.storeFile(fileName, input);
            input.close();
            ftpClient.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }
}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值