您的位置:首页 > 编程语言 > PHP开发

第27章 FTP:文件传送协议

2018-11-11 22:09 2839 查看

27.1 引言

FTP是另一个常见的应用程序。它是用于文件传输的Internet标准。我们必须分清文件传送(file transfer)和文件存取(file access)之间的区别,前者是FTP提供的,后者是如NFS(Sun的网络文件系统,第29章)等应用系统提供的。由FTP提供的文件传送是将一个完整的文件从一个系统复制到另一个系统中。要使用FTP,就需要有登录服务器的注册帐号,或者通过允许匿名FTP的服务器来使用(本章我们将给出这样的一个例子)。

与Telnet类似,FTP最早的设计是用于两台不同的主机,这两个主机可能运行在不同的操作系统下、使用不同的文件结构、并可能使用不同字符集。但不同的是,Telnet获得异构性是强制两端都采用同一个标准:使用7比特ASCII码的NVT。而FTP是采用另一种方法来处理不同系统间的差异。FTP支持有限数量的文件类型(ASCII,二进制,等等)和文件结构(面向字节流或记录)。

参考文献959 [Postel和Reynolds 1985] 是FTP的正式规范。该文献叙述了近年来文件传输的历史演变。

27.2 FTP协议

FTP与我们已描述的另一种应用不同,它采用两个TCP连接来传输一个文件。

  1. 控制连接以通常的客户服务器方式建立。服务器以被动方式打开众所周知的用于FTP的端口(21),等待客户的连接。客户则以主动方式打开TCP端口21,来建立连接。控制连接始终等待客户与服务器之间的通信。该连接将命令从客户传给服务器,并传回服务器的应答。
    由于命令通常是由用户键入的,所以IP对控制连接的服务类型就是“最大限度地减小迟延”。
  2. 每当一个文件在客户与服务器之间传输时,就创建一个数据连接。(其他时间也可以创建,后面我们将说到)。
    由于该连接用于传输目的,所以IP对数据连接的服务特点就是“最大限度提高吞吐量”。

图27-1描述了客户与服务器以及它们之间的连接情况。

图27-1 文件传输中的处理过程

从图中可以看出,交互式用户通常不处理在控制连接中转换的命令和应答。这些细节均由两个协议解释器来完成。标有“用户接口”的方框功能是按用户所需提供各种交互界面(全屏幕菜单选择,逐行输入命令,等等),并把它们转换成在控制连接上发送的FTP命令。类似地,从控制连接上传回的服务器应答也被转换成用户所需的交互格式。

从图中还可以看出,正是这两个协议解释器根据需要激活文件传送功能。

27.2.1 数据表示

FTP协议规范提供了控制文件传送与存储的多种选择。在以下四个方面中每一个方面都必须作出一个选择。

第27章 FTP:文件传送协议317

1. 文件类型

  1. ASCII码文件类型(默认选择)文本文件以NVT ASCII码形式在数据连接中传输。这要求发方将本地文本文件转换成NVT ASCII码形式,而收方则将NVT ASCII码再还原成本地文本文件。其中,用NVT ASCII码传输的每行都带有一个回车,而后是一个换行。这意味着收方必须扫描每个字节,查找CR、LF对(我们在第15.2节见过的关于TFIP的ASCII码文件传输情况与此相同)。
  2. EBCDIC文件类型该文本文件传输方式要求两端都是EBCDIC系统。
  3. 图像文件类型(也称为二进制文件类型)数据发送呈现为一个连续的比特流。通常用于传输二进制文件。
  4. 本地文件类型该方式在具有不同字节大小的主机间传输二进制文件。每一字节的比特数由发方规定。对使用8bit字节的系统来说,本地文件以8bit字节传输就等同于图像文件传输。

2. 格式控制

该选项只对ASCII和EBCDIC文件类型有效。

  1. 非打印(默认选择)文件中不含有垂直格式信息。
  2. 远程登录格式控制文件含有向打印机解释的远程登录垂直格式控制。
  3. Fortran回车控制每行首字符是Fortran格式控制符。

3. 结构

  1. 文件结构(默认选择)文件被认为是一个连续的字节流。不存在内部的文件结构。
  2. 记录结构该结构只用于文本文件(ASCII或EBCDIC)。
  3. 页结构每页都带有页号发送,以便收方能随机地存储各页。该结构由TO PS-20操作系统提供(主机需求RFC不提倡采用该结构)。

4. 传输方式

它规定文件在数据连接中如何传输。

  1. 流方式(默认选择)文件以字节流的形式传输。对于文件结构,发方在文件尾提示关闭数据连接。对于记录结构,有专用的两字节序列码标志记录结束和文件结束。
  2. 块方式文件以一系列块来传输,每块前面都带有一个或多个首部字节。
  3. 压缩方式一个简单的全长编码压缩方法,压缩连续出现的相同字节。在文本文件中常用来压缩空白串,在二进制文件中常用来压缩0字节(这种方式很少使用,也不受支持。现在有一些更好的文件压缩方法来支持FTP)。

318TCP/IP详解,卷1:协议

图27-2 常用的FTP命令

下节我们将通过一些例子看到,在用户交互类型和控制连接上传送的FTP命令之间有时是一对一的。但也有些操作下,一个用户命令产生控制连接上多个FTP命令。

第27章 FTP:文件传送协议319

图27-3 应答代码3位数字中第1位和第2位的含义

第3位数字给出差错报文的附加含义。例如,这里是一些典型的应答,都带有一个可能的报文串。

• 125   数据连接已经打开;传输开始。
• 200   就绪命令。
• 214   帮助报文(面向用户)。
• 331   用户名就绪,要求输入口令。
• 425   不能打开数据连接。
• 452   错写文件。
• 500   语法错误(未认可的命令)。
• 501   语法错误(无效参数)。
• 502   未实现的 MODE ( 方式命令 ) 类型。

通常每个FTP命令都产生一行回答。例如,QUIT命令可以产生如下应答:

221 Goodbye.

如果需要产生一条多行应答,第1行在3位数字应答代码之后包含一个连字号,而不是空格,最后一行包含相同的3位数字应答代码,后跟一个空格符。例如,HELP命令可以产生如下应答:

320TCP/IP详解,卷1:协议

27.2.4 连接管理

数据连接有以下三大用途:

  1. 从客户向服务器发送一个文件。
  2. 从服务器向客户发送一个文件。
  3. 从服务器向客户发送文件或目录列表。

FTP服务器把文件列表从数据连接上发回,而不是控制连接上的多行应答。这就避免了行的有限性对目录大小的限制,而且更易于客户将目录列表以文件形式保存,而不是把列表显示在终端上。

我们已说过,控制连接一直保持到客户-服务器连接的全过程,但数据连接可以根据需要随时来,随时走。那么需要怎样为数据连接选端口号,以及谁来负责主动打开和被动打开?

首先,我们前面说过通用传输方式(Unix环境下唯一的传输方式)是流方式,并且文件结尾是以关闭数据连接为标志。这意味着对每一个文件传输或目录列表来说都要建立一个全新的数据连接。其一般过程如下:

  1. 正由于是客户发出命令要求建立数据连接,所以数据连接是在客户的控制下建立的。
  2. 客户通常在客户端主机上为所在数据连接端选择一个临时端口号。客户从该端口发布一个被动的打开。
  3. 客户使用PORT命令从控制连接上把端口号发向服务器。
  4. 服务器在控制连接上接收端口号,并向客户端主机上的端口发布一个主动的打开。服务器的数据连接端一直使用端口20。

图27-4给出了第3步执行时的连接状态。假设客户用于控制连接的临时端口是1173,客户用于数据连接的临时端口是1174。客户发出的命令是PORT命令,其参数是6个ASCII中的十进制数字,它们之间由逗点隔开。前面4个数字指明客户上的IP地址,服务器将向它发出主动打开(本例中是140.252.13.34),而后两位指明16 bit端口地址。由于16 bit端口地址是从这两个数字中得来,所以其值在本例中就是4×256+150=1174。

图27-5给出了服务器向客户所在数据连接端发布主动打开时的连接状态。服务器的端点是端口20。

图27-4 在FTP控制连接上通过的PORT命令

图27-5 主动打开数据连接的FTP服务器

第27章 FTP:文件传送协议321

当FTP客户提示我们注册姓名时,它打印了默认值(我们在客户上的注册名)。当我们敲RETURN键时,默认值被发送出去。

对一个文件列出目录的要求引发一个数据连接的建立和使用。本例体现了我们在图27-4和图27-5中给出的程序。客户要求TCP为其数据连接的终端提供一个临时端口号,并用PORT命令发送这个端口号(1174)给服务器。我们也看到一个交互用户命令(dir)成为两个FTP命令(PORT和LIST)。

322TCP/IP详解,卷1:协议

图27-6 FTP控制连接示例

第27章 FTP:文件传送协议323

图27-7 FTP数据连接示例

27.3.2 连接管理:默认数据端口

如果客户没有向服务器发出PORT命令,来指明客户数据连接端的端口号,服务器就用与控制连接正在用的相同的端口号给数据连接。这会给使用流方式(Unix FTP客户和服务器一直使用)的客户带来一些问题。正如下面所示:

Host Requirements RFC建议使用流方式的FTP客户在每次使用数据连接前发一个PORT命令来启用一个非默认的端口号。

回到先前的例子(图27-6),如果我们要求在列出第1个目录后几秒钟再列出另一个目录,那该怎么办?客户将要求其内核选择另一个临时端口号(可能是1175),下一个数据连接将建立在svr4端口1175和bsdi端口20之间。但在图27-7中服务器执行数据连接的主动打开,我们在18.6节说明了服务器将不把端口20分配给新的数据连接,这是因为本地端口号已被更早的连接使用,而且还处于2MSL等待状态。

服务器通过指明我们在18.6节中提到的SO_REUSEADDR选项,来解决这个问题。这让它把端口20分配给新连接,而新连接将从处于2MSL等待状态的端口(1174)处得到一个不一样的外部端口号(1175),这样一切都解决了。

如果客户不发送PORT命令,而在客户上指明一个临时端口号,那么情况将改变。我们可以通过执行用户命令sendport给FTP来使之发生。Unix FTP客户用这个命令在每个数据连接使用之前关闭向服务器发送PORT命令。

图27-8给出了用于两个连续LIST命令的数据连接时间系列。控制连接起自主机svr4上的端口11 76,所以在没有PORT命令的情况下,客户和服务器给数据连接使用相同的端口号(除去了窗口通知和服务类型值)。

324TCP/IP详解,卷1:协议

图27-8 两个连续LIST命令的数据连接

事件序列如下:

  1. 控制连接是建立在客户端口1176到服务器端口21上的(这里我们不展示)。
  2. 当客户为端口1176上的数据连接做被动打开时,由于该端口已被客户上的控制连接使用,所以必须确定SO_REUSEADDR选项。
  3. 服务器给端口20到端口1176的数据连接(报文段1)做主动打开。即便端口1176已在客户上被使用,客户仍会接受它(报文段2),这是因为下面这一对插口是不同的:
    <svr4,1176,bsdi,21>
    <svr4,1176,bsdi,20>
    (在bsdi上的端口号是不同的)。TCP通过查看源IP地址、源端口号、目的IP地址、目的端口号分用各呼入报文段,只要这4个元素中的一个不同,就行。
  4. 服务器对数据连接(报文段5)做主动的关闭,即把这对插口置入服务器上的一个2MSL等待。
    <svr4,1176,bsdi,20>
  5. 客户在控制连接上发送另一个LIST命令(这里我们不展示)。在此之前,客户在端口11 76上为其数据连接端做一个被动打开。客户必须再一次指明SO_REUSEADDR,这是因为端口号11 76已在使用。
  6. 服务器给从端口20到端口11 76的数据连接发出一个主动打开。在此之前,服务器必须指明SO_REUSEADDR,这是因为本地端口(20)与处于2MSL等待状态的连接是相关联的,但从18.6节所示可知,该连接将不成功。其原由是这个连接用插口对(socket pair)与步骤4中的仍处于2MSL等待状态的插口对相同。TCP规定禁止服务器发送同步信息(SYN)。这样就没办法让服务器跨过插口对的2MSL等待状态来重用相同的插口对。
    在这一步伯克利软件分发(BSD)服务器每隔5秒就重试一次连接请求,直到满18次,总共90秒。我们看到报文段9将在大约1分钟后成功(我们在第18章提到过,SVR4使用一个30秒的MSL,以两个MSL来达到持续1分钟的等待)。我们没看到在这个时间系列上的这些失败有任何同步(SYN)信息,这是因为主动打开失败,服务器的TCP不再发送一个SYN。

第27章 FTP:文件传送协议325

因为文件有4行,所以从数据连接上传输42个字节。Unix下的每一新行符(\n)被服务器转换成NVT ASCII码的2字节行结尾序列(\r\n)来传输,然后再由客户转换成原先形式来存储。

新客户试图确定服务器是否是相同类型的系统,一旦相同,就可以用二进制码(图像文件类型)来传输文件,而不是ASCII码。这可以获得两个方面的好处:

  1. 发方和收方不必查看每一字节(很大的节约)。
  2. 如果主机操作系统使用比2字节的NVT ASCII码序列更少的字节来作行尾,就会传输更少的字节数(很小的节约)。

326TCP/IP详解,卷1:协议

注册到服务器后,客户FTP自动发出SYST命令,服务器将用自己的系统类型来响应。如果应答起自字符串“215 UNIX Type:L8”,并且如果客户在每字节为8bit的Unix系统上运行,那么二进制方式(图像)将被所有文件传输所使用,除非被用户改变。

当我们取文件hello.c时,客户自动发出命令TYPE I把文件类型定成图像。这样在数据连接上只有38字节被传输。

Host Requirements RFC指出一个FTP服务器必须支持SYST命令(这曾是RFC 959中的一个选项)。但支持它的使用文本的系统(见封2)仅仅是BSD/386和AIX 3.2.2。SunOS 4.1.3和Solaris 2.x用500(不能理解的命令)来应答。SVR4采用极不大众化的应答行为500,并关闭控制连接!

27.3.4 异常中止一个文件的传输:Telnet同步信号

现在看一下FTP客户是怎样异常中止一个来自服务器的文件传输。异常中止从客户传向服务器的文件很容易—只要客户停止在数据连接上发送数据,并发出ABOR命令到控制连接上的服务器即可。而异常中止接收就复杂多了,这是因为客户要告知服务器立即停止发送数据。我们前面提到要使用Telnet同步信号,下面的例子就是这样。

我们先发起一个接收,并在它开始后键入中断键。这里是交互会话,其中初始注册被略去:

第27章 FTP:文件传送协议327

在我们键入中断键之后,客户立即告知我们它将发起异常中止,并正在等待服务器完成。服务器发出两个应答:426和226。这两个应答都是由Unix服务器在收到来自客户的紧急数据和ABOR命令时发出的。

图27-9和图27-10展示了会话时间系列。我们已把控制连接(实线)和数据连接(虚线)合在一起来说明它们之间的关系。

图27-9 异常中止一个文件的传输(前半部)

图27-9的前面12个报文段是我们所期望的。通过控制连接的命令和应答建立起文件传输,数据连接被打开,第1个报文段的数据从服务器发往客户。

328TCP/IP详解,卷1:协议

图27-10 异常中止一个文件的传输(后半部)

在图27-10中,报文段13是数据连接上来自服务器的第6个数据报文段,后跟由我们键入的中断键产生的报文段14。客户发出10个字节来异常中止传输:

<IAC,IP,IAC,DM,A,B,O,R,\r,\n>

由于20.8节中详细讨论过这个问题,我们看到有两个报文段(14和15)涉及到TCP的紧急指针(我们在图26-17中看过对Telnet问题也做相同的处理)。Host Requirements RFC指出紧急指针应指向紧急数据的最后一个字节,而多数伯克利的派生实现使之指向紧急数据最后一个字节后面的第一个字节。了解到紧急指针将(错误地)指向下一个要写的字节(数据标志,DM。在序号为54处),FTP客户进程特意写前3个字节作为紧急数据。首先写下的3字节紧急数据与紧急指针一起被立即发送,紧接着是后面7个字节(BSD FTP服务器不会出现由客户使用的紧急指针的解释问题。当服务器收到控制连接上的紧急数据时,它读下一个FTP命令,寻找ABOR或STAT,忽略嵌入的Telnet命令)。

注意到尽管服务器指出传输被异常中止(报文段18,在控制连接上),客户进程还要在数据连接上再接收14个报文段的数据(序列号是1537~5120)。这些报文段可能在收到异常中止时,还在服务器上的网络设备驱动器中排队,但客户打印“收到1536字节”,意思是在发出异常中止后(报文段14和15),略去收到的所有数据报文段。

第27章 FTP:文件传送协议329

330TCP/IP详解,卷1:协议

来自服务器的出错应答是无需加以说明的。

第27章 FTP:文件传送协议331
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: