简介:FTP(文件传输协议)是网络环境中服务器与客户端之间进行文件交换的通用标准。此压缩包聚焦Java环境下基于Apache Commons Net库实现FTP上传与下载的完整流程,适合具备一定Java基础、需要完成远程文件同步、网站部署或自动化运维功能的开发者。资源共包含2个文件,分别是可直接运行的Java源码和配套的jar依赖包,整体压缩包仅106KB,轻量易用。源码围绕FTP实际操作闭环编写,覆盖FTPClient对象建立连接、21端口默认配置、账号密码登录、主动与被动模式切换、二进制传输类型设置、目录切换与文件列表获取,并通过retrieveFile、storeFile配合输入输出流完成文件下载与上传,同时包含logout、disconnect等释放步骤;针对IOException等常见异常也给出了基本处理方式,可帮助读者理解FTP编程核心接口与调用顺序。已有249人学习下载,对刚接触服务器文件传输的Java开发者有较好的参考价值。 上周一个朋友跑来问我:公司内网一台Linux服务器上堆了上百GB的报表和素材,Windows电脑要定时从上面取文件,之前全靠U盘和共享目录来回倒,麻烦不说还总漏版本。我说你直接开FTP不就行了?他愣了一下:FTP这么老的东西还有人用?
有这种想法的人真不少。FTP诞生于1971年,比HTTP还早,又是明文传输,看上去早该退休了。可实际做运维久了你会发现,在服务器上传下载文件这件事上,FTP依然是很多场景里最皮实、最省事的方案。今天这篇我就围绕“FTP从服务器上传下载文件”完整讲一遍:服务端怎么搭、客户端怎么连、常见报错到底是怎么回事,尽量做到看完能直接上手。
1. 这个“老协议”为什么到今天还在被大量使用
1.1 设备生态决定了它退不了场
很多人对FTP的印象停留在“老、慢、明文”,恨不得一棍子打死。可真到了生产环境,你会发现相当多的场景里只有FTP是跨设备最顺畅的选项。
举几个我实际遇到的例子。办公室里常见的柯美(柯尼卡美能达)复合机,设置“扫描到文件夹”时,底层协议选项里通常都有FTP,管理员在机器上填服务器IP、端口、账号密码就能把扫描件直接传到服务器指定目录。再比如各品牌监控NVR、录播主机的录像归档功能,也普遍内置FTP上传。那些几十个G的录像文件要定时备份出来,很多设备对WebDAV和SMB的支持一言难尽,但对FTP的兼容性反而最好。
这就是FTP的生存空间:在服务器与各类终端、嵌入式设备的文件交换中,它像个“最大公约数”。你不需要在每台设备上装额外客户端,不需要配置复杂的域环境,只要服务器开好服务,任何系统、任何设备都能用一套逻辑传文件。
1.2 FTP和SFTP、SMB、HTTP放在一起比一比
做选型时我习惯把这些协议拉出来对比,别一上来就抱着FTP不放,也别一听FTP就否决。
| 协议 | 加密 | 典型端口 | 适合场景 | 主要短板 |
|---|---|---|---|---|
| FTP | 不加密 | 21 | 内网互传、设备对接 | 口令和文件内容可被抓包 |
| FTPS | TLS加密 | 990或21 | 需要加密的FTP场景 | 配置多一层,客户端要选加密方式 |
| SFTP | SSH加密 | 22 | 运维传文件、公网传输 | 嵌入式设备支持不如FTP广 |
| SMB | 可选加密 | 445 | Windows局域网共享 | Linux与Windows互配麻烦 |
注意一点,SFTP和FTP完全是两种协议,SFTP跑在SSH通道上,更安全,但很多打印机、NVR只认传统FTP协议,所以它替代不了FTP在设备生态里的位置。
1.3 一句话选型结论
内网设备互传、办公扫描归档、服务器之间临时交换文件,直接用FTP,省心。公网跨地域、强安全要求的场景,老老实实换SFTP或加TLS的FTPS。Windows电脑之间的日常共享,用SMB更顺手,别拿FTP硬扛。这个判断先定下来,后面所有的搭建和排错才有方向。
2. 服务器端搭建:Linux + vsftpd 和 Windows Server + IIS 两条路
2.1 先搞明白FTP的“双通道”,后面排错全靠它
FTP和HTTP最大的不同在于它有两个连接:控制连接和数据连接。
控制连接走21端口,登录、输入命令都在这一条上完成。但真正传输目录列表或文件内容时,会另外再开一条数据连接。这就是为什么很多人奇怪“明明21端口通了,怎么一列目录就卡住”。
数据连接又有两种模式。主动模式(PORT)是服务器主动从20端口去连客户端的高位端口,问题在于客户端通常躲在路由器或防火墙后面,服务器根本连不进来。被动模式(PASV)是服务器先开放一段高位端口,等客户端连过去。现在绝大多数场景都用被动模式,这也决定了后面必须放行服务器上的一段范围端口,不然传输必然失败。
你可以把控制连接理解成打电话订餐,主动模式是餐厅派人开车把饭送到家,被动模式是你自己到餐厅取餐窗口拿。大多数家庭的地址(NAT)外卖员不好找,所以干脆改成自取,这就是被动模式存在的理由。
2.2 Linux下用vsftpd搭一个能直接用的FTP
Linux服务器上我基本都用vsftpd,轻量、稳定、配置直观。Ubuntu和Debian系用apt,CentOS和RHEL系用yum,命令略有差异,配置思路一致。
# Ubuntu / Debian sudo apt update sudo apt install vsftpd -y # CentOS / RHEL sudo yum install vsftpd -y装完先备份原始配置,这是一个非常重要的习惯:
sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak然后编辑 /etc/vsftpd.conf,下面这份是我在实际业务里验证过的基础配置,可以直接用:
listen=YES listen_ipv6=NO anonymous_enable=NO local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES xferlog_enable=YES connect_from_port_20=YES xferlog_std_format=YES chroot_local_user=YES allow_writeable_chroot=YES pasv_enable=YES pasv_min_port=30000 pasv_max_port=31000 pam_service_name=vsftpd逐项解释几个关键点。anonymous_enable=NO是关闭匿名访问,否则任何人都能读你的文件。local_enable=YES和write_enable=YES是允许本地账号登录并写入。chroot_local_user=YES把用户锁在自己的家目录里,登录后看不到服务器其他路径,安全上很有必要。allow_writeable_chroot=YES这个选项容易被忽略,新版vsftpd默认禁止chroot目录可写,不加这一项,用户能连上但传文件时会报错“500 OOPS”。
然后是创建专用FTP用户。这里推荐用不能登录shell的系统用户,只用来做FTP:
sudo useradd -m -s /sbin/nologin ftpuser sudo passwd ftpuser启动服务并设置开机自启:
sudo systemctl enable --now vsftpd sudo systemctl status vsftpd验证方式很简单,先在本机试:ftp localhost,输入账号密码后能进到目录就说明基本正常。接着要在防火墙里放行21端口和刚才配置的30000-31000数据端口:
sudo firewall-cmd --permanent --add-service=ftp sudo firewall-cmd --permanent --add-port=30000-31000/tcp sudo firewall-cmd --reload如果你用的是云服务器实例,还要记得去云控制台的安全组里同步放行这些端口。这一步漏掉的人非常多,表现就是客户端能登录,但列目录或传文件时干等超时。
2.3 Windows Server下用IIS搭FTP
Windows Server 2012和2016的搭建路径基本一致,图形化操作对新手友好。先在“服务器管理器”里添加角色和功能,勾选“Web服务器(IIS)”下的FTP服务器选项,包括FTP服务和FTP扩展。
装好后打开IIS管理器,在左侧右键“网站”,选择“添加FTP站点”。名称随意,物理路径指向你准备共享的文件夹。接着绑定IP:如果是内网就用服务器内网IP,端口默认21,SSL那一栏我一般选“允许SSL”或“无SSL”,然后身份验证勾选“基本”,授权规则里指定允许访问的Windows账号或用户组,勾上读取和写入权限。
这里有个容易踩的坑:文件系统权限和FTP授权是两套东西。就算你在IIS里给了写入权限,如果Windows文件夹属性里的NTFS权限没给到对应的Windows用户,上传一样会失败。所以建好站点后,还要去共享文件夹的“属性 → 安全”里添加该用户,分配修改和写入权限。最后记得在Windows防火墙入站规则里放行21端口以及被动模式端口范围(默认1024-65535比较宽泛,生产环境建议在IIS FTP站点的“FTP防火墙支持”里指定一段窄范围)。
3. 客户端上传下载实操:图形工具、资源管理器、命令行三种方式
3.1 FileZilla是首选,配置一次能用到天荒地老
我做过很多次文件服务器交付,客户端一律推荐FileZilla。开源免费、跨平台、支持断点续传,最关键的是它的报错信息比Windows资源管理器清楚太多。
打开FileZilla后,按Ctrl+S进入站点管理器,新建站点,填主机IP、端口21,协议选FTP,加密方式根据服务器端配置选“普通FTP”或“要求显式的FTP over TLS”,登录类型选“正常”,填用户名和密码。连上之后,左边是本地目录,右边是服务器目录,直接把文件从左拖到右就是上传,从右拖到左就是下载,下面传输队列会实时显示进度和速度。
处理大文件时,FileZilla底部传输队列里的任务可以右键暂停,再右键选择“继续”就能断点续传,这个功能在内网传输几个G的镜像文件时特别实用。传输中途断网、超时,重新连上后别急着从头传,先在队列里点继续,能省大量时间。
3.2 资源管理器直接访问FTP,两台电脑直连传文件
不想装软件时,Windows资源管理器也能访问FTP。在地址栏直接输入:
ftp://192.168.1.100回车后会弹出登录框,填用户名密码就能像打开本地文件夹一样浏览。好处是零安装、上手快;坏处也不少:中文文件名经常乱码,传输大文件不稳定,报错信息非常简陋。
“两台电脑怎么通过FTP传文件”这个问题,本质就是一台做服务端、一台做客户端。A电脑装好vsftpd或IIS FTP,B电脑在资源管理器里输A的IP访问,前提是两台机器在同一内网,并且A的防火墙放行了21和被动端口范围。很多人在这一步卡住,其实不是FTP配置错了,而是防火墙没放行数据端口,导致能登录但一复制文件就出错。
3.3 命令行方式,适合脚本自动化
如果你要写脚本定时从服务器拉取数据,客户端最好用curl或lftp。
curl下载和上传:
# 下载服务器文件到本地 curl -u ftpuser:密码 ftp://192.168.1.100/data/report.zip -O # 上传本地文件到服务器 curl -u ftpuser:密码 -T local.zip ftp://192.168.1.100/upload/lftp更强大,尤其适合目录镜像和多线程下载。交互模式里常用的两个命令:
lftp ftpuser:密码@192.168.1.100 # 镜像服务器目录到本地 mirror /remote/dir /local/dir # 镜像本地目录到服务器 mirror -R /local/dir /remote/dir下载超大文件时可以用lftp的多线程功能,比如分成8段并行下载:
lftp -e 'pget -n 8 /data/bigfile.iso -o /local/bigfile.iso; quit' ftpuser:密码@192.168.1.100cron里挂一条lftp命令,就能实现每天凌晨自动从服务器拉取备份,这是手工操作完全比不上的。
4. 高频报错排查实录:从启动失败到传不了文件
4.1 vsftpd启动失败:failed to start vsftpd daemon
这个错我在网上见过无数人问,包括拼写成“vstpd”的也大有人在。遇到启动失败,第一件事不是改配置,而是看日志:
sudo systemctl status vsftpd sudo journalctl -u vsftpd -n 50 --no-pager按我的经验,最常见原因有三类。
第一,配置文件里有非法内容。vsftpd对配置格式比较挑剔,等号前后不能有多余空格,不能用全角空格,某个参数拼错都会导致启动失败。如果是从网上复制配置,这种事特别容易发生。
第二,listen参数冲突。有时候为了图省事,把listen=YES和listen_ipv6=YES同时写了,服务会报“Address already in use”。同一台机器上同时监听IPv4和IPv6的21端口就是会打架,要么只开listen=YES,要么把listen_ipv6=NO。
第三,SELinux介入。CentOS系尤其常见,systemctl status看着一切正常,服务就是起不来或不工作。可以临时用以下命令验证:
sudo setsebool -P ftpd_full_access on如果生效了,说明问题确实在SELinux策略,这条命令保持on状态即可。Debian/Ubuntu系没有这个麻烦。
4.2 FileZilla提示“不安全的服务器”和FTP over TLS
很多用户第一次连FTP服务器时,FileZilla会弹出一个警告:“服务器不支持由FTP over TLS加密的连接,要继续吗?”有人会以为服务器出故障了,其实不是。
这是FileZilla的安全策略。新版客户端默认要求服务器支持显式TLS(即FTPS),检测到服务器只提供纯FTP时,它会明确警告你明文传输的风险。如果是在可信内网,可以勾选“允许使用不安全的FTP”继续连接;如果服务器在公网或传输敏感数据,老老实实去给vsftpd配TLS,方法我在下一章写。
这里还有一层需要理解:FileZilla警告只是“提示风险”,不是“连接不了”。很多人看到红锁图标就慌,其实只要确认网络环境可控,继续用没毛病。
4.3 资源管理器报0x800FFFF或复制文件出错
Windows资源管理器访问FTP时报0x800FFFF,是个让人很头疼的通用错误。这个错误码本身不精确,但根据我遇到的情况,绝大多数指向数据连接失败,而不是登录认证失败。
碰到这类错误,先用FileZilla试连同一台服务器。如果FileZilla能正常列目录、传文件,说明服务端没问题,问题出在资源管理器这边。接着检查Internet选项里“局域网设置”是否勾选了代理服务器,FTP流量一旦被代理拦一道,就容易出现这种莫名其妙的问题,取消代理再试。
还有一种情况是复制文件时报错或文件名变成乱码。原因是Linux服务器上的中文文件名是UTF-8编码,而Windows资源管理器默认按系统本地编码解析,两者对不上就乱码。解决方案不是去改服务器文件名,而是改用FileZilla这类能正确协商UTF-8的客户端。老派运维总说“FTP客户端首选非Explorer”,就是因为它的隐蔽问题太多。
4.4 列表卡住、传输卡在0%:数据通道被防火墙拦
这是FTP部署里出现频率最高的问题:能登录,能发命令,但列目录一直转圈,传文件永远停在0%。
现在你应该明白了,这是因为控制连接通了,数据连接被拦在中间。服务器配置了被动模式后,数据连接会使用30000-31000这样的高位端口,如果防火墙或云安全组没有放行这段范围,客户端发送LIST或STOR命令后服务器开了一个端口,客户端连不进来,整个传输就卡死了。
解决思路分三步走。第一步确认vsftpd配置里有pasv_enable=YES和pasv_min_port、pasv_max_port。第二步检查防火墙是否放行对应端口范围。第三步检查云安全组。我见过很多人在服务器本地防火墙折腾半天,最后发现是云控制台安全组没放行,这种低级失误在客户现场尤其常见。
# iptables环境 iptables -A INPUT -p tcp --dport 21 -j ACCEPT iptables -A INPUT -p tcp --dport 30000:31000 -j ACCEPT改完再测试时,可以在服务端执行tail -f /var/log/vsftpd.log观察连接记录,连一次看一次日志,能非常直观地看到客户端请求是否到达了数据端口。
5. 读写权限与大文件传输的进阶经验
5.1 让共享文件夹可以被指定用户读写
“如何让FTP上的一个文件夹可以读写”也是搜索热词,说明很多人卡在权限上。Linux下,你要先确定哪个Linux用户拥有这个目录,然后给目录设置合适的属主和权限。
sudo mkdir -p /data/share sudo chown ftpuser:ftpuser /data/share sudo chmod 755 /data/share755的意思是属主可读写执行,组和其他人只能读和执行。如果要多个FTP账号共同维护一个目录,可以建用户组:
sudo groupadd ftpgroup sudo usermod -aG ftpgroup ftpuser sudo chown -R root:ftpgroup /data/share sudo chmod -R 775 /data/share这里要注意chroot的限制。当chroot_local_user=YES时,用户被锁在自己的家目录里,哪怕你有/data/share的权限也看不到。如果业务上必须共享家目录以外的文件夹,推荐用mount --bind把目录绑进用户家目录:
sudo mkdir -p /home/ftpuser/share sudo mount --bind /data/share /home/ftpuser/share echo "/data/share /home/ftpuser/share none bind 0 0" >> /etc/fstab还有local_umask=022决定新建文件的默认权限,022会让新文件变成644,新目录变成755。如果你希望组内协作更顺畅,可以改成007,但要注意这样新文件的组权限是7,安全性要求高的目录慎用。
5.2 大文件传输:断点续传、超时与并发控制
服务器上传下载大文件是另一个高频需求。内网传输大文件,单线程一般能跑满千兆,但怕的是网络抖动。一抖就断,断了又从头传,再大的带宽也扛不住。
断点续传是必须掌握的技能。FileZilla里右键传输中的任务选“继续”即可;命令行场景下,curl用-C -参数从断点继续下载:
curl -u ftpuser:密码 -C - -O ftp://192.168.1.100/bigfile.isolftp镜像时加-c参数也是同理,中断后再次执行会自动续传未完成的部分。
并发下载提升速度,可以用lftp的pget,多个线程同时拉同一文件,效果立竿见影:
lftp -e 'pget -n 8 /data/bigfile.iso -o /local/bigfile.iso; quit' ftpuser:密码@192.168.1.100服务器端也要调整一下并发限制。vsftpd默认对单个IP的并发连接数有限制,多线程下载时就容易报“421 Service not available”,需要在vsftpd.conf里增加:
max_per_ip=10如果服务器端空闲会话超时太短,大文件传得慢时容易被服务器主动断开,可以适当调大:
idle_session_timeout=6005.3 顺手把FTPS/TLS开上,彻底堵明文传输风险
既然前面反复提到“不安全的服务器警告”,这里就给出vsftpd启用TLS的完整配置。先给自己签一张自签证书,内网用足够:
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \ -keyout /etc/pki/tls/private/vsftpd.key \ -out /etc/pki/tls/certs/vsftpd.pem然后在vsftpd.conf里追加:
ssl_enable=YES allow_anon_ssl=NO force_local_data_ssl=YES force_local_logins_ssl=YES rsa_cert_file=/etc/pki/tls/certs/vsftpd.pem rsa_private_key_file=/etc/pki/tls/private/vsftpd.key重启vsftpd后用FileZilla连接,站点管理器里把加密方式选成“要求显式的FTP over TLS”,连接时接受自签证书警告即可正常传输。开了这层之后,账号密码和文件内容都走TLS加密,公网传输才算真正安全。
最后提一句我自己维护服务器的习惯:FTP用户一律用sbin/nologin系统账号,目录一律chroot,被动端口单独规划一小段,防火墙和云安全组严格按段放行,平时基本不用多看。FTP这个协议确实不年轻了,但放在内网互传、设备导数据、服务器间临时交换文件这些场景里,它依然是最不容易出岔子的选择。希望这篇能帮你把文件服务器一条龙跑通,少踩几个来回折腾的坑。
本文还有配套的精品资源,点击获取