介绍
FTP是文件传输协议(File Transfer Protocal)的简写,主要完成与远程计算机的文件传输。
FTP采用客户/服务器模式,客户机与服务器之间利用TCP建立连接,客户可以从服务器上下载文件,也可以把本地文件上传至服务器。
访问方式
客户机访问FTP服务器方法:
- 浏览器直接访问:ftp://FTP地址
- 文件管理器访问:ftp://FTP地址
- xftp客户端访问:连接属性内设置主机IP,端口,用户名,密码即可
- dos访问
模式
PORT(主动模式)
PORT中文称为主动模式,工作的原理: FTP客户端连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,客户端随机开放一个端口(1024以上),发送 PORT命令到FTP服务器,告诉服务器客户端采用主动模式并开放端口;FTP服务器收到PORT主动模式命令和端口号后,通过服务器的20端口和客户端开放的端口连接,发送数据。
PASV(被动模式)
PASV是Passive的缩写,中文成为被动模式,工作原理:FTP客户端连接到FTP服务器的21端口,发送用户名和密码登录,登录成功后要list列表或者读取数据时,发送PASV命令到FTP服务器, 服务器在本地随机开放一个端口(1024以上),然后把开放的端口告诉客户端, 客户端再连接到服务器开放的端口进行数据传输。
两种模式的比较
从上面的运行原来看到,主动模式和被动模式的不同简单概述为: 主动模式传送数据时是“服务器”连接到“客户端”的端口;被动模式传送数据是“客户端”连接到“服务器”的端口。
主动模式需要客户端必须开放端口给服务器,很多客户端都是在防火墙内,开放端口给FTP服务器访问比较困难。
被动模式只需要服务器端开放端口给客户端连接就行了。
参考文献 http://www.cnblogs.com/mawanglin2008/articles/3607767.html
JAVA中的使用实例
java中,内网用被动模式 ,外网连接时用主动模式,服务器相应改动
连接FtpClient
/** * 获取FTPCLIENT */ public static FTPClient getFtpClient() throws SocketException, IOException { FTPClient ftp = new FTPClient(); // 连接 ftp.connect(host);// 连接FTP服务器 ftp.login(username, password);// 登陆FTP服务器 ftp.setControlEncoding("UTF-8"); // 中文支持 ftp.setFileType(FTPClient.BINARY_FILE_TYPE); // ftp.enterLocalPassiveMode(); // 被动模式 ftp.enterLocalActiveMode(); // 主动模式 ftp.changeWorkingDirectory(ftpPath); return ftp; }
下载文件
/** * 下载ftp文件 */ public static String download(String filepath, String filename) { OutputStream os = null; String result = ""; FTPClient ftpClient = new FTPClient(); try { ftpClient = getFtpClient(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("FTP连接发生异常!", e); } try { String localFileName = fileTempPath + File.separator + DateUtils.getRandNum(5) + "_" + filename; File localFile = new File(localFileName); os = new FileOutputStream(localFile); ftpClient.retrieveFile(filepath, os); result = localFileName; System.out.println("ftp dowmload over"); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("FTP客户端出错!", e); } finally { try { os.close(); ftpClient.logout(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("关闭FTP连接发生异常!", e); } } return result; }
上传文件
/** * 上传ftp文件 */ public static String upload(byte[] fileByte, String fileId, String fileType) { InputStream input = null; String result = ""; FTPClient ftpClient = new FTPClient(); try { ftpClient = getFtpClient(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("FTP连接发生异常!", e); } try { input = new ByteArrayInputStream(fileByte); //切换到上传目录 String ftpFilePath = "411400/411400-FG/" + DateUtils.getYear() + "/" + DateUtils.getMonth(); if (!ftpClient.changeWorkingDirectory(ftpPath + "/" + ftpFilePath)) { //如果目录不存在创建目录 String[] dirs = ftpFilePath.split("/"); String tempPath = ftpPath; for (String dir : dirs) { if (null == dir || "".equals(dir)) continue; tempPath += "/" + dir; if (!ftpClient.changeWorkingDirectory(tempPath)) { if (!ftpClient.makeDirectory(tempPath)) { System.out.println("create " + tempPath + " failure"); return result; } else { ftpClient.changeWorkingDirectory(tempPath); } } } } ftpClient.storeFile(fileId + "." + fileType, input); System.out.println("ftp upload over"); result = ftpFilePath + "/" + fileId + "." + fileType; } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("FTP客户端出错!", e); } finally { try { input.close(); ftpClient.logout(); } catch (IOException e) { e.printStackTrace(); throw new RuntimeException("关闭FTP连接发生异常!", e); } } return result; }