简介:计算机网络基础课程配套文档,围绕文件传输协议(FTP)与简单文件传输协议(TFTP)展开,依据RFC 959梳理了FTP从ARPANET时期至今的发展脉络。文档详细讲解FTP模型中的控制连接与数据连接,说明二者在会话过程中的不同角色,并逐一介绍文件类型、格式控制、文件结构(文件/记录/页)及传输方式(流/块/压缩)等数据表示选项,还整理了常用FTP命令与三位应答码的含义。同时对比TELNET采用NVT方式解决异构性的思路,突出FTP的交互访问、格式说明与授权控制等服务特性;后半部分对TFTP的轻量设计、基于UDP的超时重传机制、512字节分块传输原理作了简明归纳。资源为单个doc文档,容量142KB,内容密集、结构清晰,适合计算机网络基础学习者预习、复习或作为备课参考,目前已有207人浏览学习,是快速掌握FTP协议知识的一份实用资料。
1. 计算机网络基础课程里的文件传输协议:看懂FTP,后面应用层全是降维
计算机网络基础课程讲到应用层时,文件传输协议(File-Transfer-Protocol)是第一个让人又爱又恨的章节。说它简单,是因为命令少;说它难,是主动模式和被动模式那两张图,能劝退一半人。这篇笔记不聊虚的:用一台电脑、一个抓包工具,把FTP从课程概念走成一次完整的可复现实验,连状态码、NAT、防火墙的坑一起看掉。适合期末备考,以及刚接手内网文件交换的运维同学。
FTP的标准定义在RFC 959,1985年定稿,如今仍活跃在银行对账单、嵌入式设备升级和老门户下载区。搞懂它,再看HTTP、SFTP、对象存储的传输机制,会发现都是同一个问题的不同解法:控制信息和数据怎么传递。
2. FTP的连接模型与主动/被动模式:先搞清楚21和20为什么分两个端口
2.1 控制连接与数据连接:FTP为什么设计成两路
FTP区别于其他应用层协议最大的点:控制连接和数据连接分开。控制连接默认走21端口,承载USER、PASS、CWD、QUIT这些命令和服务器的状态码回复。数据连接走20端口或随机高位端口,只负责传输文件内容和目录列表。这个“带外控制”的设计,让FTP可以在传输大文件时继续下发命令,比如取消传输,这是HTTP做不到的。
课程文档里常把这部分画成“客户端-服务器”两条竖线,但落到抓包上,你会发现数据连接的发起方向也分两种,这就是下面的PORT和PASV。
2.2 主动模式(PORT)与被动模式(PASV):NAT环境下不是玄学
主动模式:客户端在控制连接上发送PORT命令,告诉服务器“我这边开了个端口等你连”,然后服务器用20端口主动去连客户端这个端口。问题来了:客户端如果在家用路由器后面,服务器根本连不进去。这是内网实验最容易翻车的地方。
被动模式:客户端发PASV命令,服务器在自己那侧开一个随机高位端口,把这端口通过227响应告诉客户端,由客户端去连接。这样服务器的数据连接是“被连”,所以对NAT后的客户端友好,但对服务器防火墙不友好——因为端口是随机的,防火墙不知道要放行哪个。
用一张表说清差异:
| 对比项 | 主动模式 PORT | 被动模式 PASV |
|---|---|---|
| 数据连接由谁发起 | 服务器(20端口 → 客户端) | 客户端(→ 服务器随机端口) |
| 对客户端NAT的影响 | 大概率失败 | 基本可用 |
| 对服务器防火墙的要求 | 放行20出站即可 | 要放行一整段pasv端口 |
| 常见使用场景 | 服务器和客户端同一内网 | 跨公网、云服务器 |
| 课程考试爱问的点 | 数据连接源端口是20 | 227响应里怎么解析端口 |
常见做法是:局域网实验用主动模式,跨网段或云主机用被动模式。vsftpd、Serv-U这些服务器软件都默认开启PASV支持,但你要在配置里显式指定pasv_min_port和pasv_max_port,否则防火墙还是没法开。
2.3 从谢希仁到自顶向下:这份课程文档对应的考点图谱
408、王道和期末复习对FTP的考法,其实集中在几条:控制连接端口21,数据连接谁发起(主动20/被动随机);FTP没有加密,口令明文传输;与HTTP相比,FTP为什么用两个连接;以及状态码的常见语义,比如220、331、230表示登录前三个阶段正常。湖科大教书匠的应用层视频、谢希仁《计算机网络》第六章、计算机网络自顶向下第二版的应用层章节都把这些点讲透了,差别在于范例:谢希仁习惯用主动模式举例,自顶向下则更偏向讲解PASV在NAT穿透上的作用。
我建议复习时把课程文档里的“报文格式”小节,切到Wireshark抓包里对照着看。只有这样,“PORT 192,168,1,100,200,1”这种行才会从记忆负担变成真正的协议语言。
3. 把课程文档变成可复现实验:在局域网内搭一个最小FTP服务
3.1 三行命令起一个匿名FTP服务:Linux和Windows的做法
课程文档里的实验通常要求“在你自己的电脑上搭建FTP服务器”。最省事的不是vsftpd,因为配置项多、认证环节多;我一般先用Python的pyftpdlib起一个临时服务,验证客户端、抓包链路都通了,再换正式服务器。
先装再起:
pip install pyftpdlib python3 -m pyftpdlib -p 21 -i 0.0.0.0 --write这里-p 21是监听FTP控制端口21;-i 0.0.0.0是监听所有接口,便于局域网其他机器访问;--write允许匿名用户上传,做实验方便,真实环境别加。跑完看到“FTP server started on port 21”就说明起来了。Windows下如果让本机ftp命令连自己,要找开发模式或防火墙放行入站21端口;Linux下用netstat -tlnp验证21端口正在LISTEN。
Linux正规做法是vsftpd,最小配置三行就够实验:
sudo apt install vsftpd sudo sed -i 's/^#*anonymous_enable=.*/anonymous_enable=YES/' /etc/vsftpd.conf sudo systemctl restart vsftpd这里的anonymous_enable=YES对应课程文档里“匿名用户访问”的考点;生产环境建议关掉匿名、用本地用户并叠加FTP over TLS。改完用systemctl status vsftpd看一眼状态,再用netstat -tlnp确认21端口在LISTEN。
3.2 用ftp命令行完成一次完整的上传下载:十条最常用指令
客户端这边,Windows、Linux、macOS都自带ftp命令。连上去之后,一份课程实验里出现频率最高的指令顺序是:open、user、pass、dir、binary、get、put、rename、delete、quit。下面这段命令既可以用在Windows的DOS窗口,也可以用在Linux Shell:
ftp 192.168.1.10 # 连上后提示 Name,输入 anonymous # 提示 Password 时直接回车或填 anonymous@ dir binary get test.zip put local.txt rename local.txt renamed.txt quit参数上,执行binary之后再get/put,就会以二进制方式传输,解决Windows和Linux换行符导致的文件损坏。dir会触发数据连接拉目录列表,我能看到服务器返回150 Opening data connection和226 Transfer complete,这对排查“清单半天出不来”很有帮助。
如果你在云服务器上做实验,把192.168.1.10换成公网IP;连不上的时候别急着喷协议,先确认是不是云安全组没放行21端口和PASV端口段——这是新手最常见的翻车原因。
3.3 用Python ftplib跑通自动收发:脚本与参数说明
课程文档之外值得加一个自动化收发的脚本,方便批量拉取文件。Python标准库自带ftplib,无需安装。最小下载脚本长这样:
from ftplib import FTP ftp = FTP() # connect("主机", 端口, timeout) ftp.connect("192.168.1.10", port=21, timeout=15) # login("用户", "密码") ftp.login("anonymous", "anonymous@") ftp.cwd("/pub") # 进入服务器的 /pub 目录 with open("down.zip", "wb") as fp: # retrbinary 用二进制方式接收文件,避免换行符转换 ftp.retrbinary("RETR up.zip", fp.write) # 上传用 storbinary,两个参数:STOR 文件名、本地文件对象 with open("local.bin", "rb") as fp: ftp.storbinary("STOR local.bin", fp) ftp.quit() # 发送 QUIT 并关闭连接这里connect的timeout是控制连接的超时,单位秒;15秒是常见值,慢速公网要调大。retrbinary的第二个参数是回调函数,直接传fp.write,让数据块边收边写,不会把整个文件读进内存。storbinary同理,边读边发。如果服务器开了TLS,把FTP()换成ftplib.FTP_TLS(),然后调用prot_p()切换到加密数据连接,写法基本不变。
这个脚本跑通后,你对FTP的理解就超过课程文档一大截:你不再依赖图形客户端的“点击连接”,而是能看到每个命令底层在做什么。跑不通时,优先检查地址、端口、TLS证书三个位置。
4. 用Wireshark验证协议交互:抓包看懂CWD、PORT、PASV
4.1 抓包准备与过滤条件:只看FTP本身
验证FTP协议,靠抓包比靠日志直观得多。打开Wireshark,选择连内网的那块网卡,过滤器输入:
ftp || ftp-data加了这两个过滤词,抓包界面就不会被ARP、TCP ACK打扰。我习惯到“编辑—首选项—协议—FTP”里把FTP data port设为20,这样主动模式的数据连接也能被正确识别。没有图形界面的环境,可以改用tshark:
tshark -i eth0 -f "tcp port 21 or tcp port 20" -Y "ftp || ftp-data"抓包前把其他下载任务停掉,避免数据连接端口号交叉造成困惑。实验时登录、切目录、下载一次即可,三步操作足够覆盖常见报文。
4.2 一次典型会话逐包拆解:从USER到RETR
操作完成后,Wireshark里会有一条清晰的交互链。拿一次局域网内的实验报文拆开看:
| 序号 | 包方向 | 内容 | 含义 |
|---|---|---|---|
| 1 | Client → Server | USER anonymous | 提交用户名 |
| 2 | Server → Client | 331 Password required | 服务器要密码 |
| 3 | Client → Server | PASS anonymous@ | 提交密码(明文) |
| 4 | Server → Client | 230 Logged in | 登录成功 |
| 5 | Client → Server | CWD /pub | 切换目录 |
| 6 | Server → Client | 250 Directory changed | 切换成功 |
| 7 | Client → Server | PASV | 请求被动模式 |
| 8 | Server → Client | 227 Entering Passive Mode (192,168,1,10,244,100) | 告诉客户端连哪个端口 |
| 9 | Client → Server | RETR test.dat | 请求下载 |
| 10 | Server → Client | 150 Opening data connection | 数据连接建立 |
| 11 | Server → Client(数据连接) | 若干TCP segment | 文件内容 |
| 12 | Server → Client | 226 Transfer complete | 传输结束 |
第8行的227响应是重点:括号里前4个数是服务器IP,后2个数244和100组成的端口,计算方式为244×256+100=62564。课程文档常让你“学会这个换算”,抓包现场看一次就能记住。第11行的数据连接,在实验里经常遇到“清单卡住”,原因往往是数据连接被交换机或防火墙拦了,不是FTP挂了。
4.3 对照课程文档里的状态码:1xx到5xx的含义速查
FTP协议的状态码是“三位数字+文本”结构。期末或面试里,熟记下面几组基本够用:
| 状态码 | 含义 | 出现时机 |
|---|---|---|
| 110 | 重新启动标记回复 | 断点续传(REST)时 |
| 150 | 数据连接即将开启 | RETR/STOR/LIST前 |
| 220 | 服务就绪 | 刚连上时首次响应 |
| 226 | 数据传输完成 | 文件收完后最后一个码 |
| 227 | 进入被动模式 | PASV响应的内容 |
| 230 | 用户登录成功 | PASS验证之后 |
| 331 | 需要密码 | 收到USER后返回 |
| 425/426 | 数据连接无法建立/中断 | 防火墙或NAT出问题时 |
| 450/550 | 文件不可用/操作失败 | 权限或路径错误最常见 |
我的经验是,背状态码表时把“数字”还原成“这条命令的上一句和下一句”。看到150,下一个必然是数据包或226;看到227,解析后面的括号比背数字更重要。这样遇到没见过的状态码,也能猜出大致类别。
5. 避坑指南:FTP最容易翻车的5个现场与排查路径
5.1 连上了但ls卡住:主动模式撞上NAT
现象:同一个局域网内的FTP可以登录,但跨网段或云服务器上用dir命令就卡住,直到超时。
原因:客户端在NAT后面,服务器主动连接客户端的数据端口时连不进来。这与主动模式在客户端NAT下必然失败的原理是同一个问题。
解决:客户端改用被动模式,大多数图形客户端在“设置—连接模式”里可直接切PASV;服务器端则要确保启用了pasv_enable=YES,并且把pasv_min_port和pasv_max_port区间同步给防火墙。
5.2 ASCII模式传二进制文件损坏:文件大小都变了
现象:通过FTP下载一个zip或exe,打开提示损坏,文件大小和源文件不一样。
原因:默认传输模式是ASCII,在这种模式下,FTP会在传输时把换行符在CRLF和LF之间转换。对文本文件没问题,对二进制文件来说,0x0A被转成0x0D0A,直接改字节内容。
解决:传输前执行binary命令,或者客户端勾选“二进制模式”。脚本里用retrbinary和storbinary即可。这个坑在课程实验里最常见,因为文档篇幅有限,没把“文件类型必须匹配”讲透。
5.3 防火墙放行了21端口还是连不上数据连接
现象:服务器防火墙和云安全组都放行了21,但下载或列目录时提示425 Cannot open data connection。
原因:数据连接所需端口不在放行范围。21只管控制连接;被动模式还需要整段高位端口放行;主动模式则要保证服务器20端口出站与返回路径都通。
解决:以vsftpd为例,配置:
pasv_enable=YES pasv_min_port=30000 pasv_max_port=30100配置后重启vsftpd,并在防火墙放行该端口段。firewalld下执行:
firewall-cmd --permanent --add-port=30000-30100/tcp firewall-cmd --reload这一步做掉之后,大部分“能登录不能下”的问题都能解决。
5.4 上传大文件中断后要从头开始:FTP不适合广域网大文件
现象:几百兆文件传到一半网络抖动,客户端提示已断开,重新上传又从头开始。
原因:FTP的断点续传能力太弱。REST命令虽然定义在协议里,但多数服务器和客户端支持得不好;即使支持,也没有统一的校验机制。XCRC、XMD5这类扩展遇到不认识的服务器就直接被忽略。
解决:百兆级别以上的文件、公网传输,不建议走FTP,用SFTP或HTTP分片上传更可靠。如果必须保留FTP,就把传输限定在内网段,并在脚本里追加md5校验,下载后自动比对,及时发现坏文件。
5.5 vsftpd配置了却起不来:PAM和监听配置冲突
现象:照着教程改完vsftpd.conf,systemctl restart vsftpd,服务启动失败,日志里全是500 OOPS。
原因:vsftpd版本不同,有两个高频冲突点:listen=YES与listen_ipv6=YES同时开启会报错,因为IPV4和IPV6监听不能同时启用;另一个是本地用户对应shell在/etc/shells里不存在,比如用户用了nologin,vsftpd会拒绝启动。
解决:配置里保留listen和listen_ipv6其中一个;再确认本地用户shell在/etc/shells中存在。排查时执行:
sudo journalctl -u vsftpd -n 20 sudo systemctl status vsftpd如果看到“500 OOPS: vsftpd: refusing to run with writable root inside chroot()”,是chroot目录权限过宽,把目录权限改成755。日志信息比网上零散教程可靠得多。
6. 从FTP到SFTP/HTTP:什么时候该迁移,什么时候留在FTP
FTP最大的问题不是技术老化,而是明文传输——在公网上用ftp命令输入的密码,任何抓包工具都能直接读出来。遇到“上公网、传敏感数据”的场景,我一般直接用SFTP:它是SSH的子系统,走22端口,加密传输,且能复用现有用户体系,一条命令就能上传:
scp -P null local.tar.gz user@server:/data/如果项目里没有被迫继承的FTP链路,我连考虑都不会考虑FTP。
什么时候该留下FTP?内网嵌入式设备、老工业终端、只开放公网下载区的场景。这些设备根本不支持SSH,或者固件里只实现RFC 959。我给客户留FTP时的习惯是:把vsftpd单独放在隔离网段,只对指定IP开放;强制启用TLS的ssl_enable=YES;匿名访问彻底关掉。另一个技巧是给FTP用户做白名单处理,在/etc/ftpusers里把root、bin这类系统账号全部禁掉,避免弱口令风险。
最后一个建议:别把FTP实验局限在“能用就行”。把第4章的抓包做一遍,你就能自己回答课程文档里“状态码226和150谁先到”“PASV后的端口怎么算”这些问题。我踩过的坑里,最亏的不是协议不会,而是排错半小时发现只是防火墙端口没开。多把抓包和配置这两件事打通,你会比只背状态码的人少走很多弯路。希望帮到你。
本文还有配套的精品资源,点击获取