搭建FTP服务器
安装
#切换到root用户的根目录
cd ~
#yum命令安装
yum install -y vsftpd
#设置服务开机自启
systemctl enable vsftpd.service
#启动FTP服务
systemctl start vsftpd.service
#查看FTP服务端口号
netstat -antup | grep ftp
配置FTP服务器
使用yum安装之后,FTP服务的配置文件路径是:/etc/vsftpd/vsftpd.conf
使用vim命令编辑该配置文件。
FTP服务器有两种访问模式,分别是:匿名模式、本地用户模式。一般推荐本地用户模式,它更加安全
方式一:匿名模式配置
#找到匿名模式和匿名上传权限,确认这两个配置为开启状态
anonymous_enable=YES
anon_upload_enable=YES
#然后在文件末尾添加以下配置,配置前也可以逐个检查一下这些配置是否已经存在
#开启被动模式。
pasv_enable=YES
#设置被动模式下,建立数据传输可使用的端口范围的最小值。
#建议您把端口范围设置在一段比较高的范围内,例如50000~50010,有助于提高访问FTP服务器的安全性。
pasv_min_port=50000
#设置被动模式下,建立数据传输可使用的端口范围的最大值。
pasv_max_port=50010
ESC退出编辑文件编辑模式,然后保存写入文件的内容
#为ftp用户添加以下文件的读写权限
chmod o+w /var/ftp/pub/
#重启FTP服务
systemctl restart vsftpd.service
方式二:本地用户模式
#添加ftp用户并修改用户密码
adduser ftptest
passwd ftptest
#这里添加用户时可能会报错,说不能打开/etc/passwd文件,解决办法请参考我的另一个博客
https://www.jianshu.com/p/d3bf0d12f127
#创建保存文件的目录,并修改目录拥有者为你创建的ftp用户
mkdir /var/ftp/test
chown -R ftptest:ftptest /var/ftp/test
修改vsftpd.conf文件
#除下面提及的参数,其他参数保持默认值即可。
#修改下列参数的值:
#禁止匿名登录FTP服务器。
anonymous_enable=NO
#允许本地用户登录FTP服务器。
local_enable=YES
#监听IPv4 sockets。
listen=YES
#在行首添加#注释掉以下参数:
#关闭监听IPv6 sockets。
#listen_ipv6=YES
#在配置文件的末尾添加下列参数:
#设置本地用户登录后所在目录。
local_root=/var/ftp/test
#全部用户被限制在主目录。
chroot_local_user=YES
#启用例外用户名单。
chroot_list_enable=YES
#指定例外用户列表文件,列表中用户不被锁定在主目录。
chroot_list_file=/etc/vsftpd/chroot_list
#开启被动模式。
pasv_enable=YES
allow_writeable_chroot=YES
#本示例中为Linux服务器的公网IP。
pasv_address=<FTP服务器公网IP地址>
#设置被动模式下,建立数据传输可使用的端口范围的最小值。
#建议您把端口范围设置在一段比较高的范围内,例如50000~50010,有助于提高访问FTP服务器的安全性。
pasv_min_port=50000
#设置被动模式下,建立数据传输可使用的端口范围的最大值。
pasv_max_port=50010
创建意外用户名单文件chroot_list文件,不管你实际中会不会用到该文件,都必须创建该文件,注意:必须创建!必须创建!必须创建!!!
vim /etc/vsftpd/chroot_list
#重启FTP服务
systemctl restart vsftpd.service
最后需要注意的是,如果你的服务器是阿里云或者其他的云服务器,它是有安全策略的,需要你去云服务管理控制台,开启几个端口:21、50000-50010
然后测试访问即可。
测试工具可以使用这个
https://www.filezilla.cn/download?spm=a2c4g.11186623.2.11.6bd05c3eaYSx4D
封装FTP工具类
引入maven配置
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.5</version>
</dependency>
工具类
说明:
工具类是借鉴这篇博客的,不过封装的方法有些小问题,我测试之后修改了几个参数
,博客地址:https://blog.csdn.net/baidu_34389984/article/details/79314160
然后FTP的官方文档地址是:http://commons.apache.org/proper/commons-net/apidocs/org/apache/commons/net/ftp/FTPClient.html
感兴趣的大佬可以自行研究一下
package com.newcoder.utils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.net.ftp.FTPClient;
import java.io.IOException;
import java.io.InputStream;
/**
* @author LengYouNuan
* @create 2021-08-03 下午5:01
*/
@Log4j2
public class FTPUtils {
//设置私有不能实例化
private FTPUtils() {
}
/**
* 上传
*
* @param hostname ip或域名地址
* @param port 端口
* @param username 用户名
* @param password 密码
* @param inputStream 要上传文件的输入流
* @param saveName 设置上传之后的文件名
* @return
*/
public static boolean upload(String hostname, int port, String username, String password, InputStream inputStream, String saveName) {
boolean flag = false;
FTPClient ftpClient = new FTPClient();
//1 测试连接
if (connect(ftpClient, hostname, port, username, password)) {
if (storeFile(ftpClient, saveName, inputStream)) {
flag = true;
disconnect(ftpClient);
}
disconnect(ftpClient);
}
return flag;
}
/**
* 断开连接
*
* @param ftpClient
* @throws Exception
*/
public static void disconnect(FTPClient ftpClient) {
if (ftpClient.isConnected()) {
try {
ftpClient.disconnect();
log.error("已关闭连接");
} catch (IOException e) {
log.error("没有关闭连接");
e.printStackTrace();
}
}
}
/**
* 测试是否能连接
*
* @param ftpClient
* @param hostname ip或域名地址
* @param port 端口
* @param username 用户名
* @param password 密码
* @return 返回真则能连接
*/
public static boolean connect(FTPClient ftpClient, String hostname, int port, String username, String password) {
boolean flag = false;
try {
//ftp初始化的一些参数
ftpClient.connect(hostname, port);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
ftpClient.setControlEncoding("UTF-8");
if (ftpClient.login(username, password)) {
log.info("连接ftp成功");
flag = true;
} else {
log.error("连接ftp失败,可能用户名或密码错误");
try {
disconnect(ftpClient);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
log.error("连接失败,可能ip或端口错误");
e.printStackTrace();
}
return flag;
}
/**
* 上传文件
*
* @param ftpClient
* @param saveName 全路径。如/home/public/a.txt
* @param fileInputStream 要上传的文件流
* @return
*/
public static boolean storeFile(FTPClient ftpClient, String saveName, InputStream fileInputStream) {
boolean flag = false;
try {
if (ftpClient.storeFile(saveName, fileInputStream)) {
flag = true;
log.error("上传成功");
disconnect(ftpClient);
}
} catch (IOException e) {
log.error("上传失败");
disconnect(ftpClient);
e.printStackTrace();
}
return flag;
}
}