速读原著-TCP/IP(FTP示例)

2020-03-18 11:17:16 浏览数 (1)

第27章 FTP:文件传送协议

27.3 FTP的例子

现在看一些使用F T P的例子:它对数据连接的管理,采用 NVT ASCII码的文本文件如何发送,F T P使用Te l n e t同步信号来中止进行中的文件传输,最后是常用的“匿名 F T P”。

27.3.1 连接管理:临时数据端口

先看一下F T P的连接管理,它只在服务器上用简单 F T P会话显示一个文件。我们用- d标志(d e b u g)来运行s v r 4主机上的客户。这告诉它要打印控制连接上变换的命令和应答。所有前面冠以- - - >的行是从客户上发向服务器的,所有以 3位数字开头的行都是服务器的应答。客户的交互提示是f t p >。

当F T P客户提示我们注册姓名时,它打印了默认值(我们在客户上的注册名)。当我们敲R E T U R N键时,默认值被发送出去。

对一个文件列出目录的要求引发一个数据连接的建立和使用。本例体现了我们在图 2 7 - 4和图2 7 - 5中给出的程序。客户要求 T C P为其数据连接的终端提供一个临时端口号,并用 P O RT命令发送这个端口号( 11 7 4)给服务器。我们也看到一个交互用户命令( d i r)成为两个F T P命令(P O RT和L I S T)。

图2 7 - 6是控制连接上分组交换的时间系列(已除去了控制连接的建立和结束,以及所有窗口大小的通知)。我们关注该图中数据连接在哪儿被打开、使用和过后的关闭。

图2 7 - 7是数据连接的时间系列。图中的起始时间与图 2 7 - 6中的相同。已除去了所有窗口大小通知,但留下服务类型字段,以说明数据连接使用另一个服务类型(最大吞吐量),而不同于控制连接(最小时延)(服务类型( TO S )值在图3 - 2中)。

在时间系列上,F T P服务器执行数据连接的主动打开,从端口 2 0(称为f t p - d a t a)到来自P O RT命令的端口号( 11 7 4)。本例中还可以看到服务器在哪儿向数据连接上执行写操作,服务器对数据连接执行主动的关闭,这就告诉客户列表已完成。

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

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

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

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

服务器通过指明我们在1 8 . 6节中提到的S O _ R E U S E A D D R选项,来解决这个问题。这让它把端口2 0分配给新连接,而新连接将从处于 2 M S L等待状态的端口(11 7 4)处得到一个不一样的外部端口号(11 7 5),这样一切都解决了。

如果客户不发送P O RT命令,而在客户上指明一个临时端口号,那么情况将改变。我们可以通过执行用户命令s e n d p o r t给F T P来使之发生。Unix FTP客户用这个命令在每个数据连接使用之前关闭向服务器发送P O RT命令。

图2 7 - 8给出了用于两个连续L I S T命令的数据连接时间系列。控制连接起自主机 s v r 4上的端口11 7 6,所以在没有P O RT命令的情况下,客户和服务器给数据连接使用相同的端口号(除去了窗口通知和服务类型值)。

事件序列如下:

  1. 控制连接是建立在客户端口 11 7 6到服务器端口2 1上的(这里我们不展示)。
  1. 当客户为端口11 7 6上的数据连接做被动打开时,由于该端口已被客户上的控制连接使用,所以必须确定S O _ R E U S E A D D R选项。
  2. 服务器给端口2 0到端口11 7 6的数据连接(报文段1)做主动打开。即便端口 11 7 6已在客户上被使用,客户仍会接受它(报文段 2),这是因为下面这一对插口是不同的:
代码语言:javascript复制
<svr4, 1176, bsdi, 21>
<svr4, 1176, bsdi, 20>

(在b s d i上的端口号是不同的)。T C P通过查看源I P地址、源端口号、目的 I P地址、目的端口号分用各呼入报文段,只要这 4个元素中的一个不同,就行。 4) 服务器对数据连接(报文段 5)做主动的关闭,即把这对插口置入服务器上的一个2 M S L等待。

代码语言:javascript复制
<svr4, 1176, bsdi, 20>
  1. 客户在控制连接上发送另一个 L I S T命令(这里我们不展示)。在此之前,客户在端口11 7 6上为其数据连接端做一个被动打开。客户必须再一次指明 S O _ R E U S E A D D R,这是因为端口号11 7 6已在使用。
  2. 服务器给从端口2 0到端口11 7 6的数据连接发出一个主动打开。在此之前,服务器必须指明S O _ R E U S E A D D R,这是因为本地端口(2 0)与处于2 M S L等待状态的连接是相关联的,但从1 8 . 6节所示可知,该连接将不成功。其原由是这个连接用插口对 (socket pair)与步骤4中的仍处于2 M S L等待状态的插口对相同。T C P规定禁止服务器发送同步信息(S Y N)。

这样就没办法让服务器跨过插口对的2 M S L等待状态来重用相同的插口对。在这一步伯克利软件分发(B S D)服务器每隔5秒就重试一次连接请求,直到满1 8次,总共9 0秒。我们看到报文段9将在大约1分钟后成功(我们在第1 8章提到过,S V R 4使用个3 0秒 的M S L,以两个M S L来达到持续1分钟的等待)。我们没看到在这个时间系列上的这些失败有任何同步(S Y N)信息,这是因为主动打开失败,服务器的T C P不再发送一个S Y N。

Host Requirements RFC建议使用P O RT命令的原因是在两个相继使用数据连接之间避免出现这个2 M S L。通过不停地改变某一端的端口号,我们所说的这个问题就不会出现。

27.3.3 文本文件传输:NVT ASCII表示还是图像表示

让我们查证一下默认的文本文件传输使用 NVT ASCII码。这次不指定- d标志,所以不看客户命令,但注意到客户还将打印服务器的响应:

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

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

  1. 发方和收方不必查看每一字节(很大的节约)。 2 ) 如果主机操作系统使用比 2字节的NVT ASCII码序列更少的字节来作行尾,就会传输更少的字节数(很小的节约)。 我们可以看到使用一个 B S D / 3 8 6客户和服务器的最优效果。启动排错( d e b u g)方式来看客户F T P命令:

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

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

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

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

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

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

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

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

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

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

代码语言:javascript复制
< I A C , I P , I A C , D M , A , B , O , R ,  r ,  n

由于2 0 . 8节中详细讨论过这个问题,我们看到有两个报文段( 1 4和1 5)涉及到T C P的紧急指针(我们在图2 6 - 1 7中看过对Te l n e t问题也做相同的处理)。Host Requirements RFC指出紧急指针应指向紧急数据的最后一个字节,而多数伯克利的派生实现使之指向紧急数据最后一个字节后面的第一个字节。了解到紧急指针将(错误地)指向下一个要写的字节(数据标志,D M。在序号为5 4处),F T P客户进程特意写前 3个字节作为紧急数据。首先写下的 3字节紧急数据与紧急指针一起被立即发送,紧接着是后面 7个字节(BSD FTP 服务器不会出现由客户使用的紧急指针的解释问题。当服务器收到控制连接上的紧急数据时,它读下一个 F T P命令,寻找A B O R或S TAT,忽略嵌入的Te l n e t命令)。

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

一旦Te l n e t用户键入中断键,我们在图 2 6 - 1 7中看到U n i x客户在默认情况下不发出中断进程命令作为紧急数据。因为几乎没有机会用流控制来中止从客户进程到服务器进程的数据流,所以我们说这样就行了。F T P的客户进程也通过控制连接发送一个中断进程命令,因为两个连接正在被使用,因此没有机会用流控制来中止控制连接。为什么 F T P发送中断进程命令作为紧急数据而Te l n e t不呢?答案在于 F T P使用两个连接,而 Te l n e t只使用一个,在某些操作系统上要求一个进程同时监控两个连接的输入是困难的。 F T P假设这些临界的操作系统至少提供紧急数据在控制连接上已到达的通知,而后让服务器从处理数据连接切换到控制连接上来。

27.3.5 匿名FTP

F T P的一种形式很常用,我们下面给出它的例子。它被称为匿名 F T P,当有服务器支持时,允许任何人注册并使用F T P来传输文件。使用这个技术可以提供大量的自由信息。

怎样找出你正在搜寻的站点是一个完全不同的问题。我们将在 3 0 . 4节简要介绍。我们将把匿名F T P用在站点f t p . u u . n e t上(一个常用的匿名F T P站点)来取本书的勘误表文件。要使用匿名F T P,须使用“a n o n y m o u s”(复习数遍就能正确地拼写)用户名来注册。

当提示输入口令时,我们键入自己的电子邮箱地址。

不压缩是因为很多现行匿名 F T P文件是用Unix compress( 1 )程序压缩的,这样导致文件带有. Z的扩展名。这些文件必须使用二进制文件类型来传输,而不是 A S C I I码文件类型。

27.3.6 来自一个未知IP地址的匿名FTP

可以把一些使用匿名F T P的域名系统(D N S)特征和选路特征结合在一起。在 1 4 . 5节中我们谈到D N S中指针查询现象—取一个I P地址并返回其主机名。不幸的是并非所有系统管理员都能正确地创立涉及指针查询的名服务器。他们经常记得把新主机加入名字到地址匹配的文件中,却忘了把他们加入到地址到名字匹配的文件中。对此,可用 t r a c e r o u t e经常看到这种现象,即它打印一个I P地址,而不是主机名。

有些匿名F T P服务器要求客户有一个有效域名。这就允许服务器来记录正在执行传输的主机域名。由于服务器在来自客户 I P数据报中收到的关于客户的唯一标识是客户的 I P地址,所以服务器能叫 D N S来做指针查询,并获得客户的域名。如果负责客户主机的名服务器没有正确地创立,指针查询将失败。

要看清这个错误,我们来做以下诸步骤:

  1. 把主机s l i p(见封2的图)的I P地址换成1 4 0 . 2 5 2 . 1 3 . 6 7。这是给作者子网的一个有效I P地址,但没有涉及到n o a o . e d u域的域名服务器。
  2. 把在b s d i上S L I P连接的目的I P地址换成1 4 0 . 2 5 2 . 1 3 . 6 7。
  3. 把将数据报引向1 4 0 . 2 5 2 . 1 3 . 6 7的s u n上的路由表入口加入路由器 b s d i(回忆一下我们在9 . 2节中关于这个选路表的讨论)。 从I n t e r n e t上仍然可以访问我们的主机 s l i p,这是因为在 1 0 . 4节中路由器 g a t e w a y和n e t b正好把所有目的是子网 1 4 0 . 2 5 2 . 1 3的所有数据报都发送给路由器 s u n。路由器s u n知道利用我们在上述第 3步建立的路由表入口来如何处理这些数据报。我们所创建的是拥有完整I n t e r n e t连接性的主机,但没有有效的域名。结果,指针查询 I P地址1 4 0 . 2 5 2 . 1 3 . 6 7将失败。现在给一个我们所知的服务器使用匿名 F T P,需要一个有效的域名:

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

0 人点赞