本文主要是介绍TCP/IP详解 卷1:协议 学习笔记 第二十七章 FTP:文件传送协议,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
FTP是用于文件传输的Internet标准。
文件传送是FTP提供的功能,文件存取是如NFS等应用系统提供的功能。由FTP提供的文件传送是将一个完整的文件从一个系统复制到另一个系统中。要使用FTP,需要服务器的注册账号,或服务器允许匿名FTP。
就像Telnet,FTP设计用于两台不同的主机,这两个主机可能运行在不同的操作系统下,使用不同的文件结构,并可能使用不同的字符集,但Telnet实现异构性是强制两端都采用同一个标准,即使用7bit ASCII码的NVT,而FTP使用另一种方法处理不同系统间的差异。
FTP支持有限数量的文件类型(如ASCII、二进制)和文件结构(面向字节流或记录)。
FTP采用两个TCP连接来传输一个文件:
1.控制连接以通常的客户服务器方式建立。服务器以被动方式打开于熟知端口21,客户以主动方式打开TCP端口21。该连接将命令从客户传给服务器,并传回服务器的应答。由于命令通常是用户键入的,所以IP对控制连接的服务类型是“最大限度地减小迟延”。
2.每当一个文件在客户与服务器之间传输时,就创建一个数据连接。该连接用于传输目的,所以IP对数据连接的服务类型是“最大限度提高吞吐量”。
从上图看出,交互式用户通常不处理控制连接中转换的命令和应答,这些细节由两个协议解释器完成。用户接口方框的功能是按用户所需提供各种交互界面(全屏幕菜单选择、逐行输入命令等),并把它们转换成在控制连接上发送的FTP命令,从控制连接上传回的服务器应答也被转换成用户所需的交互格式。这两个协议解释器会根据需要激活文件传送功能。
FTP协议对文件传送的每一方面都提供了多种选择,以下方面中每个方面都必须做出一个选择:
1.文件类型:
(1)ASCII码文件类型(默认):文本文件以NVT ASCII码形式在数据连接中传输,这要求发方将本地文本文件转换成NVT ASCII码形式,而接收方将NVT ASCII码再还原成本地文本文件,其中,用NVT ASCII码传输的每行都带有一个回车,而后是一个换行,这意味这收方必须扫描每一个字节,查找CR、LF对。
(2)EBCDIC文件类型:该文本文件传输方式两端都是EBCDIC系统。
(3)图像文件类型(二进制文件类型):数据发送呈现为一个比特流,通常用于传输二进制文件。
(4)本地文件类型:该方式在具有不同字节大小的主机间传输二进制文件,每一字节的比特数由发方规定,对使用8bit字节的系统,本地文件以8bit传输就等同于图像文件传输。
2.格式控制(只对ASCII和EBCDIC文件类型有效):
(1)非打印(默认):文件中不含垂直格式信息。
(2)远程登录格式控制:文件含有向打印机解释的远程登录垂直格式控制。
(3)Fortran回车控制:每行首字符是Fortran格式控制符。
3.结构:
(1)文件结构(默认):文件被认为是一个连续的字节流,不存在内部的文件结构。
(2)记录结构:只适用于文本文件(ASCII或EBCDIC)。
(3)页结构:每页都带有页号发送,以便收方能随机地存储各页,该结构由TOPS-20操作系统提供。
4.传输方式(规定文件在数据连接中如何传输):
(1)流方式(默认):文件以字节流的形式传输。对于文件结构,发方在文件尾提示关闭数据连接;对于记录结构,有专用的两字节序列码标志记录结束和文件结束。
(2)块方式:文件以一系列块来传输,每块前面带有一个或多个首部字节。
(3)压缩方式:压缩连续出现的相同字节。在文本文件中常用来压缩空白串,在二进制文件中常用来压缩0字节。这种传输方式很少使用,有更好的文件压缩方法用于FTP。
以上所有选择的排列组合很多,但很多不是废弃了就是不为多数实现所支持,通常由Unix实现的FTP客户和服务器把选择限制如下:
1.类型:ASCII或图像。
2.格式控制:只允许非打印。
3.结构:只允许文件结构。
4.传输方式:只允许流方式。
以上选择满足主机需求RFC(Host Requirements RFC)的最小要求(该RFC也要求支持记录结构,但只有操作系统支持它才行,而Unix不支持)。
FTP命令和应答在控制连接上以NVT ASCII码形式传送,这要求在每个命令或应答的结尾都要返回CR、FL对。
一个用户命令有时产生多个FTP命令。
FTP应答都是ASCII码形式的3位数字,并跟有报文选项,FTP命令是字符串而应答是数字的原因在于,命令的选项串是面向人工处理的。
FTP的应答3位码中前两位的含义:
第3位数字给出出错报文的附加含义。
通常每个FTP命令都产生一行应答,如QUIT命令的应答为:
如果FTP命令产生了多行应答,则应答显示的结构为3位应答代码后跟-
,之后是多行应答内容,最后一行是与第一行相同的3位应答代码后跟一个空格符,如HELP命令的应答如下:
数据连接作用:
1.从客户向服务器发送一个文件。
2.从服务器向客户发送一个文件。
3.从服务器向客户发送文件或目录列表。这有利于客户将目录列表以文件形式保存,而不仅是显示在终端上。
控制连接保持客户-服务器连接的全过程,但数据连接可根据需要随时建立和断开。由于Unix环境下FTP只允许流方式传输文件且文件结尾是以关闭数据连接为标志,因此对每一个文件传输或目录列表都要建立一个全新的数据连接,过程如下:
1.客户发出命令,所以数据连接是在客户的控制下建立的。
2.客户通常在客户端主机上为数据连接端选一个临时端口号,客户在该端口上被动打开。
3.客户使用PORT命令从控制连接上把被动打开的数据连接端口号发给服务器。
4.服务器在控制连接上接收端口号,并执行数据连接的主动打开,服务器的数据连接端会使用端口20。
上图是客户使用PORT命令发送自己被动打开的数据连接端口号1174,并且假设客户的控制连接临时端口为1173。PORT命令的参数是6个ASCII表示的十进制数字,它们由逗号隔开,前四个数字指明客户的IP地址,后两位指明16bit端口号,本例中端口为4*256+150=1174。
服务器总是执行数据连接的主动打开,通常服务器也执行数据连接的主动关闭,但当客户向服务器发送流形式文件时,需要客户关闭连接,这相当于文件结束通知。
建立数据连接时,客户也可能不发出PORT命令,而由服务器向客户的控制连接的端口号发出主动打开,来结束控制连接。这是可行的,因为服务器的控制连接和数据连接使用的端口号不同,但现有实现通常不这么做。
FTP客户会向服务器发送Telnet命令(以IAC打头)来终止正在进行的文件传输或在传输过程中查询服务器,FTP中,客户只会发中断进程信号(<IAC, IP>
)和Telnet的同步信号(紧急方式下<IAC, DM>
)给服务器。如果服务器接受了客户端的一个带选项的Telnet命令(WILL、WONT、DO、DONT),它将以DONT或WONT响应。
FTP建立连接:
-d选项显示控制连接上的命令,即前面有—>的行,它是控制连接上客户发向服务器的内容,以3位数字开头的行是控制连接上服务器的应答。上图中,默认用户是rstevens,用户键入RETURN时默认值被发送。可见一个dir命令会发出PORT和LIST两个命令。
以上过程的时间序列,已省去连接建立和结束过程和所有窗口大小通知:
以下是打开数据连接的时间序列:
如果客户没有向服务器发出PORT命令来指明客户数据连接端的端口号,服务器就默认把控制连接的客户端口号当作数据连接的客户端口号,这会给使用流方式的客户带来问题。
Host Requirements RFC建议流方式的FTP客户使用PORT命令给每个数据连接都使用一个非默认的端口号。
如果上例中在列出第1个目录几秒后再要求列出另一个目录,客户将要求内核使用另一个临时端口号来建立数据连接,但如果服务端器的端口20还处于2MSL等待状态时,是无法建立连接的,解决方法是服务端使用SO_REUSEADDR选项绑定端口20,这样2MSL等待状态的端口也能绑定到新连接上,而新数据连接的客户端口会和旧的不同,so everything is OK。
客户如果不发送PORT命令指明一个客户临时端口,可使用sendport命令强制使在建立数据连接时,使客户不向服务器发送PORT命令。
以下是控制连接建立在svr4的端口1176上,且发送两个连续LIST命令的数据连接时间序列,且客户不发PORT命令(这使得客户的数据连接的端口号也是控制连接的端口1176),两次数据连接建立时两端都使用了相同的端口号:
事件序列如下:
1.控制连接建立在客户端口1176到服务器端口21上。
2.当客户为端口1176上的数据连接做被动打开(调用listen)时,由于该端口已被客户的控制连接使用,所以必须使用SO_REUSEADDR选项。
3.服务器用端口20向客户的端口1176做数据连接主动打开(报文段1)。
4.服务器对数据连接做主动关闭(报文段5),服务器把<svr4, 1176, bsdi, 20>
这对socket置入2MSL等待。TCP规定处于2MSL等待期间,禁止发送SYN。
5.客户在控制连接上发送另一个LIST命令,此次客户的被动打开也需要指明SO_REUSEADDR选项。
6.服务器再次从端口20向客户的1176端口发出一个主动打开,这个打开必须指明SO_REUSEADDR选项,因为此连接还处于2MSL等待状态。此时使用伯克利软件的服务器会每隔5秒重试一次连接请求,直到满18次,总共90秒,但上图中可见报文段9在大约1分钟后成功,这是由于SVR 4使用一个30秒的MSL,因此2MSL是1分钟,没在上图中看到失败的SYN尝试发送报文,是因为服务器的TCP主动打开失败,不会发送SYN。
Host Requirements RFC建议使用PORT命令的原因在于在两个相继使用的数据连接之间避免出现这个2MSL。通过不停改变某一端的端口号,可避免以上问题。
证明默认的文本文件传输使用NVT ASCII码,此次ftp不使用-d选项查看客户发送的命令,但客户还是会打印服务器的响应:
由上图,文件传输了42字节,但文件内容只有38字节,多出来的4字节是Unix的换行符\n被服务器转换成了NVT ASCII码的2字节行结尾序列\r\n来传输,然后客户又将其转换为了原先形式来存储,每有一个换行符,传输大小就比文件大小多1字节,由于文件有4行,因此多了4字节。
客户可确认服务器与自己是否是相同系统,一旦相同,就可以直接用二进制码(图像文件类型)传送,而不是使用ASCII码,好处如下:
1.发方和收方不必查看每个字节,以转换字符,如上例中的换行。
2.传输大小不会每行都多1字节。
另一台主机bsdi上的ftp,确定了双方的系统类型,使用-d启动debug方式查看客户的ftp命令:
由上图,注册到服务器后,客户FTP自动发出SYST命令,服务器用自己的系统类型来响应,上例中表示服务器在每字节为8bit的Unix系统上运行,如果客户也一样,那么就可以使用二进制方式传送文件。在取文件hello.c时,客户自动发送TYPE Ⅰ将文件类型定成图像,这样数据连接上只有38字节被传输。
Host Requirements RFC指出一个FTP服务器必须支持SYST命令,但支持它的系统仅有BSD/386和AIX 3.2.2,SunOS 4.1.3和Solaris 2.x用500(不能理解的命令)来应答。
异常终止客户传向服务器的文件很容易,只要客户停止在数据连接上发送数据,并发送ABOR命令(关闭数据连接)到控制连接上的服务器即可。
如果客户想让服务器停止传输文件,需要使用Telnet的同步信号,如以下例子,先发起一个文件接收,并在开始传输后键入中断键:
由上图,客户发起异常中止后,服务器发出两个应答426和226,这两个都是服务器收到客户的紧急数据和ABOR命令时发出的。以下是上例的时间序列,其中实线表示控制连接,虚线表示数据连接:
前半部通过控制连接的命令和应答建立起文件传输,数据连接被打开,第一个报文段的数据从服务器发往客户。
在后半部中,报文段13是数据连接上来自服务器的第6个数据报文段,之后我们键入中断键产生了报文段14,客户发送了以下十个字节(中断进程命令IP、数据标记DM和FTP命令ABOR)来异常中止传输:
上图中报文段14和15分开发送,是由于BSD派生实现的紧急指针指向与Host Requesrments RFC规定的指向不符,即RFC要求紧急指针应指向紧急数据的最后一个字节(即DM所在字节),而多数伯克利派生的实现指向最后一个字节之后的一个字节。FTP客户进程先写了3个字节紧急数据,并且带着紧急数据指针,而FTP服务器没有解读错误的紧急指针的问题,因为它收到紧急指针时,只会寻找ABOR或STAT命令,而忽略内嵌的Telnet命令。
尽管服务器指出传输已被异常终止(报文段18),但客户进程还接收到了14个报文段的数据(序列号是1537~5120),这可能是由于在服务器收到这些异常中止时,这些数据还在网络设备驱动器中排队,但客户打印收到了1536字节,表示异常中止后,丢弃之后收到的所有数据报文段。
匿名FTP允许任何人传输文件,要使用匿名FTP,用户名需使用anonymous,密码为空。
DNS的指针查询可用一个IP地址获取主机名,但有些系统管理员会忘记将新加入的主机信息加入到IP地址到主机名的映射文件中,因此,traceroute中经常可看到打印IP地址而非主机名的现象。
有些匿名FTP要求客户有一个有效域名,这样服务器可以记录下此域名。由于服务器从客户的IP数据报中收到的关于客户的唯一标识是客户的IP地址,所以服务器会用DNS做指针查询,如果负责客户主机的域名服务器没有正确创立,指针查询将失败。以下匿名连接时连接失败的原因就是如上所述:
这篇关于TCP/IP详解 卷1:协议 学习笔记 第二十七章 FTP:文件传送协议的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!