一、概述
- 将某台计算机中的文件通过网络传送到可能相距很远的另一台计算机中,是一项基本的网络应用,即文件传送。
- 文件传送协议FTP (File Transfer Protocol)是因特网上使用得最广泛的文件传送协议。
- FTP提供交互式的访问,允许客户指明文件的类型与格式(如指明是否使用ASCII码),并允许文件具有存取权限(如访问文件的用户必须经过授权,并输入有效的口令)。
- FTP屏蔽了各计算机系统的细节,因而适合于在异构网络中任意计算机之间传送文件。
- RFC 959 很早就成为了因特网的正式标准。
二、 工作原理
2.1 两个连接
FTP客户和服务器之间要建立以下两个并行的TCP连接:
-
控制连接,在整个会话期间一直保持打开,用于传送FTP相关控制命令。
-
数据连接,用于文件传输,在每次文件传输时才建立,传输结束就关闭。
默认情况下,FTP使用TCP 21端口进行控制连接,TCP 20端口进行数据连接。但是,是否使用TCP 20端口建立数据连接与传输模式有关,主动方式使用TCP 20端口,被动方式由服务器和客户端自行协商决定。(默认是被动的)
ps:临时端口号是大于等于1024的随机端口(这里是说客户端,控制连接端口N,数据连接端口N+1)。
2.2 安全性
FTP本身并不加密数据,因此传输敏感信息时可能会受到威胁。
为了增强安全性,可以使用FTPS(FTP over SSL/TLS)或SFTP(SSH File Transfer Protocol)。
ftp连接池、实体类、实现类、配置类、工具类
三、代码实现:
1. 选择合适的库
- Apache Commons Net: 一个常用的库,用于处理 FTP 操作。它提供了全面的 FTP 功能和 API。
- Java FTP Client Libraries: 例如,
jsch
或ftp4j
也是常用的库。
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.8.0</version>
</dependency>
2. 连接配置和初始化
- 设置连接参数: 包括 FTP 服务器的地址、端口号、用户名和密码。
- 选择 FTP 模式: FTP 有主动模式(Active Mode)和被动模式(Passive Mode)。被动模式通常更适用于穿越防火墙或 NAT 的环境。
import org.apache.commons.net.ftp.FTPClient;
public class FTPConnectExample {
public static void main(String[] args) {
FTPClient ftpClient = new FTPClient();
try {
// 连接到 FTP 服务器
ftpClient.connect("ftp.example.com");
ftpClient.login("username", "password");
System.out.println("Connected and logged in successfully.");
// 其他操作...
} catch (IOException ex) {
ex.printStackTrace();
} finally {
// 确保连接被断开
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
3. 连接状态检查
- 连接测试: 在执行操作之前,测试是否能成功连接到 FTP 服务器。
- 处理连接超时: 设置适当的连接超时和读取超时值,以防止长时间等待。
- 状态监控: 定期检查连接状态,确保连接没有意外断开。
public class FTPStatusCheckExample {
public static void main(String[] args) {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect("ftp.example.com");
ftpClient.login("username", "password");
ftpClient.enterLocalPassiveMode();
// 检查连接是否有效
if (ftpClient.isConnected() && ftpClient.login("username", "password")) {
System.out.println("Connection is active.");
} else {
System.out.println("Connection is not active.");
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
// 确保连接被断开
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
4. 重连机制
- 自动重连: 实现自动重连功能,当连接断开时能够自动尝试重新连接。
- 重连策略: 设置重连次数和间隔时间,避免在短时间内过于频繁地尝试重连。
public class FTPReconnectExample {
private static final int MAX_RETRIES = 5;
private static final long RETRY_DELAY_MS = 5000;
public static void main(String[] args) {
FTPClient ftpClient = new FTPClient();
int retries = 0;
while (retries < MAX_RETRIES) {
try {
ftpClient.connect("ftp.example.com");
ftpClient.login("username", "password");
ftpClient.enterLocalPassiveMode();
System.out.println("Connected successfully.");
// Perform FTP operations...
break; // Exit loop if connection is successful
} catch (IOException ex) {
retries++;
System.out.println("Failed to connect. Retrying (" + retries + "/" + MAX_RETRIES + ")...");
try {
Thread.sleep(RETRY_DELAY_MS);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
}
5. 文件操作
- 上传/下载文件: 使用 FTP 客户端库提供的方法进行文件上传和下载。
- 文件列表: 列出 FTP 服务器上的文件和目录。
- 文件删除和重命名: 支持文件的删除和重命名操作。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.ftp.FTPClient;
public class FTPFileTransferExample {
public static void main(String[] args) {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect("ftp.example.com");
ftpClient.login("username", "password");
ftpClient.enterLocalPassiveMode();
// 上传文件
String localFilePath = "localfile.txt";
String remoteFilePath = "/path/to/remote/file.txt";
try (InputStream inputStream = new FileInputStream(localFilePath)) {
boolean uploaded = ftpClient.storeFile(remoteFilePath, inputStream);
System.out.println("File upload " + (uploaded ? "successful." : "failed."));
}
// 下载文件
String downloadPath = "downloadedfile.txt";
try (FileOutputStream outputStream = new FileOutputStream(downloadPath)) {
boolean downloaded = ftpClient.retrieveFile(remoteFilePath, outputStream);
System.out.println("File download " + (downloaded ? "successful." : "failed."));
}
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
public class FTPFileManagementExample {
public static void main(String[] args) {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect("ftp.example.com");
ftpClient.login("username", "password");
ftpClient.enterLocalPassiveMode();
// 删除文件
String fileToDelete = "/path/to/remote/fileToDelete.txt";
boolean deleted = ftpClient.deleteFile(fileToDelete);
System.out.println("File deletion " + (deleted ? "successful." : "failed."));
// 重命名文件
String oldFileName = "/path/to/remote/oldFileName.txt";
String newFileName = "/path/to/remote/newFileName.txt";
boolean renamed = ftpClient.rename(oldFileName, newFileName);
System.out.println("File rename " + (renamed ? "successful." : "failed."));
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
6. 安全性
- 加密:为保障数据安全,可以使用FTPS(FTP over SSL/TLS)或SFTP(SSH File Transfer Protocol)。
- 认证机制:使用强认证机制保护用户名和密码,确保传输过程的安全性。
7. 资源管理
- 在完成FTP操作后,需要确保及时关闭FTP连接并释放占用的资源,防止资源泄漏。
public class FTPResourceManagementExample {
public static void main(String[] args) {
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect("ftp.example.com");
ftpClient.login("username", "password");
ftpClient.enterLocalPassiveMode();
// 执行FTP操作...
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
参考:
【网络协议详解】——FTP系统协议(学习笔记)_ftp协议详解-CSDN博客
【实战-干货】手把手带你搭建自己的FTP服务器,实现文件上传、下载_搭建ftp服务器_ftp服务器怎么搭建-CSDN博客