文件传输协议(FTP)诞生于1971年,至今已经有40多年历史。作为最基础、最常用的互联网协议之一,它到现在依然发挥着重要作用。
和大多数网络协议不一样,FTP 是一个非常“奇葩”的网络协议,说它奇葩主要有以下两点原因:
第一,FTP 有两个通道:控制通道和数据通道。控制通道用来传输客户端发送给服务器的指令以及服务器返回的响应,数据通道则负责实际的数据传输。
第二,FTP 有主动模式和被动模式两种工作方式,两者最大的区别在于数据通道由哪一方主动发起连接。
接下来我们详细分析一下 FTP 协议。
和 HTTP 协议一样,FTP 的控制连接也是基于文本指令进行通信的,但 FTP 是一个有状态的协议,这一点和 SMTP 更为相似。
FTP 常用的指令包括:
CWD XCWD CDUP XCUP SMNT* QUIT PORT PASV
EPRT EPSV ALLO* RNFR RNTO DELE MDTM RMD
XRMD MKD XMKD PWD XPWD SIZE SYST HELP
NOOP FEAT OPTS AUTH* CCC* CONF* ENC* MIC*
PBSZ* PROT* TYPE STRU MODE RETR STOR STOU
APPE REST ABOR USER PASS ACCT* REIN* LIST
NLST STAT SITE MLSD MLST
FTP的两个通道
为了验证 FTP 确实存在两条连接,首先用 FlashFXP 登录一个 FTP 服务器 ftp.ietf.org,然后用 netstat 查看本地 Socket 状态:
netstat -an | findstr 4.31.198.44
TCP 192.168.1.56:65392 4.31.198.44:21 ESTABLISHED
可以看到,此时只有一个本地端口 65392 与远程 FTP 的 21 端口建立连接。
接下来尝试下载服务器上的文件,并不断监控本地 Socket 状态,发现除了远程的 21 号端口外,还有其它端口被连接,而且这些端口会不断变化。
第一次:
TCP 192.168.1.56:65479 4.31.198.44:21 ESTABLISHED
TCP 192.168.1.56:65480 4.31.198.44:61254 ESTABLISHED
第二次:
TCP 192.168.1.56:65479 4.31.198.44:21 ESTABLISHED
第三次:
TCP 192.168.1.56:65479 4.31.198.44:21 ESTABLISHED
TCP 192.168.1.56:65481 4.31.198.44:60724 ESTABLISHED
第四次:
TCP 192.168.1.56:65479 4.31.198.44:21 ESTABLISHED
TCP 192.168.1.56:65482 4.31.198.44:62712 SYN_SENT
进一步观察可以发现,每传送一个文件,都会建立一个新的数据连接,完成传送后再关闭。查看 FlashFXP 可以确认,此时使用的是被动模式。
我打开 FlashFXP 的主动模式,然后再次查看 Socket 状态。
第一次:
TCP 192.168.1.56:49375 4.31.198.44:21 ESTABLISHED
第二次:
TCP 192.168.1.56:49375 4.31.198.44:21 ESTABLISHED
TCP 192.168.1.56:49387 4.31.198.44:20 SYN_RECEIVED
第三次:
TCP 192.168.1.56:49375 4.31.198.44:21 ESTABLISHED
TCP 192.168.1.56:49390 4.31.198.44:20 LAST_ACK
第四次:
TCP 192.168.1.56:49375 4.31.198.44:21 ESTABLISHED
TCP 192.168.1.56:49391 4.31.198.44:20 SYN_RECEIVED
可以看到,服务器 21 号端口对应的控制连接一直保持不变,而数据连接则会根据每次传输不断建立和关闭。继续监控本地 Socket 的监听状态,可以发现主动模式下客户端还会监听一个本地端口,用于接收服务器发起的数据连接。从这里我们基本可以总结出 FTP 主动模式和被动模式的区别:
主动模式下,数据连接由服务器主动连接客户端;被动模式下,数据连接由客户端主动连接服务器。
这里的“主动”和“被动”是从客户端的角度来描述的。
主动模式
主动模式下,FTP 客户端首先从一个随机的非特权端口(通常大于1023)连接服务器的 21 号控制端口。随后,客户端监听另一个端口,并通过 PORT 指令把这个端口的信息告诉服务器。
服务器收到请求之后,通过自己的 20 号端口连接客户端指定的数据端口。

整个过程可以简单理解为:
- 客户端连接服务器的
21号控制端口; - 客户端监听一个用于数据连接的端口,并通过
PORT告诉服务器; - 服务器向客户端指定的端口发起数据连接;
- 建立数据连接后进行文件传输。
主动模式最大的特点,就是服务器需要主动向客户端发起连接。
被动模式
主动模式存在一个明显的问题:服务器需要主动连接客户端,而现在的客户端环境非常复杂,很多客户端位于路由器或防火墙之后,服务器很难直接连接到客户端。
因此,被动模式被设计出来。
被动模式下,服务器继续监听 21 号控制端口。当需要进行数据传输时,客户端发送 PASV 指令,服务器开启一个用于数据连接的监听端口,并把这个端口信息返回给客户端。
客户端随后主动连接服务器指定的数据端口,建立数据连接并进行数据传输。

因此,被动模式的基本过程是:
- 客户端连接服务器的
21号控制端口; - 客户端发送
PASV指令; - 服务器开启数据端口,并把端口信息返回给客户端;
- 客户端主动连接服务器的数据端口;
- 建立连接后进行数据传输。
这就是 FTP 主动模式和被动模式最核心的区别。
从整个过程来看,FTP 的确是一个比较特殊的协议:控制连接长期存在,而文件列表、下载、上传等实际数据传输则通过独立的数据连接完成;同时,数据连接又存在主动和被动两种建立方式。
也正因为如此,FTP 在遇到 NAT、防火墙等网络环境时,往往比 HTTP 等协议更复杂。
评论0
欢迎分享你的看法,也欢迎补充不同的实践经验。