概述
FTP是另一个常见的应用程序。它是用于文件传输的Internet标准。我们必须分清文件传送( file transfer)和文件存取 (file access)之间的区别,前者是FTP提供的,后者是如NFS)等应用系统提供的。由FTP提供的文件传送是将一个完整的文件从一个系统复制到另一个系统中。要使用FTP,就需要有登录服务器的注册帐号,或者通过允许匿名FTP的服务器来使用
FTP最早的设计是用于两台不同的主机,这两个主机可能运行在不同的操作系统下、使用不同的文件结构、并可能使用不同字符集。FTP支持有限数量的文件类型(ASCII,二进制,等等)和文件结构(面向字节流或记录)。
FTP协议
FTP采用两个TCP连接来传输一个文件。
- 控制连接以通常的客户服务器方式建立。服务器以被动方式打开众所周知的用于FTP的端口(21),等待客户的连接。客户则以主动方式打开TCP端口21,来建立连接。控制连接始终等待客户与服务器之间的通信。该连接将命令从客户传给服务器,并传回服务器的应答。
由于命令通常是由用户键入的,所以IP对控制连接的服务类型就是“最大限度地减小迟延”。 - 每当一个文件在客户与服务器之间传输时,就创建一个数据连接。
由于该连接用于传输目的,所以IP对数据连接的服务特点就是“最大限度提高吞吐量”。
下图描述了客户与服务器以及它们之间的连接情况:

从图中可以看出,交互式用户通常不处理在控制连接中转换的命令和应答。这些细节均由两个协议解释器来完成。标有“用户接口”的方框功能是按用户所需提供各种交互界面(全屏幕菜单选择,逐行输入命令,等等),并把它们转换成在控制连接上发送的FTP命令。类似地,从控制连接上传回的服务器应答也被转换成用户所需的交互格式。
从图中还可以看出,正是这两个协议解释器根据需要激活文件传送功能。
数据表示
FTP协议规范在以下四个方面中每一个方面都必须作出一个选择:
文件类型
a. ASCII码文件类型 (默认选择)文本文件以NVT ASCII码形式在数据连接中传输。这要求发方将本地文本文件转换成NVT ASCII码形式,而收方则将NVT ASCII码再还原成本地文本文件。其中,用NVT ASCII码传输的每行都带有一个回车,而后是一个换行。这意味着收方必须扫描每个字节,查找CR、LF对
b. EBCDIC文件类型该文本文件传输方式要求两端都是EBCDIC系统。
c. 图像文件类型(也称为二进制文件类型)数据发送呈现为一个连续的比特流。通常用于传输二进制文件。
d. 本地文件类型该方式在具有不同字节大小的主机间传输二进制文件。每一字节的比特数由发方规定。对使用8bit字节的系统来说,本地文件以8bit字节传输就等同于图像文件传输。
传输方式
FTP规定文件在数据连接中如何传输。
a. 流方式:(默认选择)文件以字节流的形式传输。对于文件结构,发方在文件尾提示关闭数据连接。对于记录结构,有专用的两字节序列码标志记录结束和文件结束。
b. 块方式:文件以一系列块来传输,每块前面都带有一个或多个首部字节。
c. 压缩方式:一个简单的全长编码压缩方法,压缩连续出现的相同字节。在文本文件中常用来压缩空白串,在二进制文件中常用来压缩 0字节(这种方式很少使用,也不受支持。)
通常由Unix实现的FTP客户和服务器把我们的选择限制如下:
- 类型:ASCII或图像。
- 格式控制:只允许非打印。
- 结构:只允许文件结构。
- 传输方式:只允许流方式。
这就限制我们只能取一、两种方式:ASCII或图像(二进制)。
FTP命令
命令和应答在客户和服务器的控制连接上以 NVT ASCII码形式传送。这就要求在每行结尾都要返回CR、LF对(也就是每个命令或每个应答)。
从客户发向服务器的Telnet命令(以IAC打头)只有中断进程(<IAC,IP>)和Telnet的同步信号(紧急方式下<IAC , DM >)。如果服务器接受了客户端的一个带选项的Telnet命令(WILL,WONT,DO或DONT ),它将以DONT 或WONT响应。
下面是一些常用的命令:

FTP应答
应答都是ASCII码形式的3位数字,并跟有报文选项。其原因是软件系统需要根据数字代码来决定如何应答,而选项串是面向人工处理的。由于客户通常都要输出数字应答和报文串,一个可交互的用户可以通过阅读报文串(而不必记忆所有数字回答代码的含义)来确定应答的含义。
应答3位码中每一位数字都有不同的含义。下图给出了应答代码第1位和第2位的含义:

第3位数字给出差错报文的附加含义。例如,这里是一些典型的应答,都带有一个可能的报文串。
- 125 数据连接已经打开;传输开始。
- 200 就绪命令。
- 214 帮助报文(面向用户)。
- 331 用户名就绪,要求输入口令。
- 425 不能打开数据连接。
- 452 错写文件。
- 500 语法错误(未认可的命令)。
- 501 语法错误(无效参数)。
- 502 未实现的M O D E (方式命令)类型。
通常每个FTP命令都产生一行回答。
连接管理
数据连接有以下三大用途:
- 从客户向服务器发送一个文件。
- 从服务器向客户发送一个文件。
- 从服务器向客户发送文件或目录列表。
FTP服务器把文件列表从数据连接上发回,而不是控制连接上的多行应答。这就避免了行的有限性对目录大小的限制,而且更易于客户将目录列表以文件形式保存,而不是把列表显示在终端上。
流的传输数据连接建立一般过程如下:
- 正由于是客户发出命令要求建立数据连接,所以数据连接是在客户的控制下建立的。
- 客户通常在客户端主机上为所在数据连接端选择一个临时端口号。客户从该端口发布一个被动的打开。
- 客户使用PORT命令从控制连接上把端口号发向服务器。
- 服务器在控制连接上接收端口号,并向客户端主机上的端口发布一个主动的打开。服务器的数据连接端一直使用端口20。
服务器总是执行数据连接的主动打开。通常服务器也执行数据连接的主动关闭,除非当客户向服务器发送流形式的文件时,需要客户来关闭连接(它给服务器一个文件结束的通知)。
客户也有可能不发出PORT命令,而由服务器向正被客户使用的同一个端口号发出主动打开,来结束控制连接。这是可行的,因为服务器面向这两个连接的端口号是不同的:一个是20,另一个是21。
FTP的例子
连接管理:临时数据端口
客户要求TCP为其数据连接的终端提供一个临时端口号,并用PORT命令发送这个端口号给服务器。
在时间系列上,FTP服务器执行数据连接的主动打开,从端口20(称为ftp-data)到来自PORT命令的端口号。
连接管理:默认数据端口
如果客户没有向服务器发出PORT命令,来指明客户数据连接端的端口号,服务器就用与控制连接正在用的相同的端口号给数据连接。这会给使用流方式( Unix FTP客户和服务器一直使用)的客户带来一些问题
服务器通过指明SO_REUSEADDR选项,来解决这个问题。这让它把端口20分配给新连接,而新连接将从处于2MSL等待状态的端口处得到一个不一样的外部端口号,这样一切都解决了。
如果客户不发送 PORT命令,而在客户上指明一个临时端口号,那么情况将改变。我们可以通过执行用户命令 sendport给FTP来使之发生。Unix FTP客户用这个命令在每个数据连接使用之前关闭向服务器发送PORT命令。
文本文件传输:NVT ASCII表示还是图像表示
用二进制码传输文件可以获得两个方面的好处:
- 发方和收方不必查看每一字节(很大的节约)。
- 如果主机操作系统使用比2字节的NVT ASCII码序列更少的字节来作行尾,就会传输更少的字节数(很小的节约)。
异常中止一个文件的传输:Telnet 同步信号
异常中止从客户传向服务器的文件很容易—只要客户停止在数据连接上发送数据,并发出ABOR命令到控制连接上的服务器即可。而异常中止接收就复杂多了,这是因为客户要告知服务器立即停止发送数据
一旦Telnet用户键入中断键,Unix客户在默认情况下不发出中断进程命令作为紧急数据。因为几乎没有机会用流控制来中止从客户进程到服务器进程的数据流,所以我们说这样就行了。FTP的客户进程也通过控制连接发送一个中断进程命令,因为两个连接正在被使用,因此没有机会用流控制来中止控制连接。
至于为什么FTP发送中断进程命令作为紧急数据而不是Telnet,是因为FTP使用两个连接,而Telnet只使用一个,在某些操作系统上要求一个进程同时监控两个连接的输入是困难的。FTP假设这些临界的操作系统至少提供紧急数据在控制连接上已到达的通知,而后让服务器从处理数据连接切换到控制连接上来。
来自一个未知IP地址的匿名FTP
有些匿名FTP服务器要求客户有一个有效域名。这就允许服务器来记录正在执行传输的主机域名。由于服务器在来自客户IP数据报中收到的关于客户的唯一标识是客户的IP地址,所以服务器能叫DNS来做指针查询,并获得客户的域名。如果负责客户主机的名服务器没有正确地创立,指针查询将失败。