分类:
2008-11-21 18:03:43
RFC 959 File Transfer Protocol (ftp)
2.3 the ftp model
1. user server之间的通讯
user-pi 和 server-pi之间建立control connection, 而data connection 是user-dtp和server-dtp之间建立的与control connection分开。
user-pi是user-protocol intepreter
user-dtp是user data transfer process
及用户和server之间通过telnet建立control连接,然后向server发送命令,以及data connectin需要用到的一些参数,如端口。然后用户端的host(可以不与当前用户所在host为同一台host)在指定的端口上listen,server发来连接请求,然后建立data connection。
2. server server之间的通讯
还可以在多个server之间建立通讯,前提是一个user与多个server建立了control connection,分别向其发送命令,参数等,使受他控制的server之间可以建立数据连接。
3.ftp 与 telnet之间的关系
(1)ftp的control connection使用telnet通讯
(2)可以使用系统已有的telnet模块
(3)可以将telnet协议中的功能加入到我们自己的ftp程序中,由于我们用到的telnet功能并不多,所以对telnet的支持没必要全部,所以也不难实现。
3.1 Data representation and storage
关注的是文件的表示和存储,与传输方法关系不大。其实关注的就是文件本身的格式对ftp传输的影响。
内容包括了Data types,以及Data structures。
Data types包括了ASCII, EBCDIC, IMAGE, LOCAL一共4种
Data structures包括:file structure, record structure, page structure三种
用得比较多的是ASCII/IMAGE,而EBCDIC和LOCAL用得很少了。
1.ASCII type
默认的,必须要实现的,特别是传输文本文件时,除非双方如果用EBCDIC type更高效。比如上方都使用的EBCDIC type来存储文件,那么传输时,也可以用这种类型,就不需要两边的转换了。
发送方将本地的存储格式转换成标准的NVT-ASCII 8-bit格式,然后传输,接受方将标准的NVT-ASCII格式转换成自己的格式。
2.EBCDIC type
格式:TYPE A
也是8-bit,是IBM曾经采用过的一种格式,它不同于传统的7-bit ASCII,它采用了8-bit.它适合发送接受双方都是EBCDIC格式的场合。
End-Of-Line用NL字符。
3.IMAGE type
格式:TYPE I
就是binary方式,文件被视为连续的bits, 一定要支持的,多用于二进制文件。
4.LOCAL type
格式TYPE L n (n为logical byte size,用十进制表示)
这个模式其实主要用于word-oriented的机器而不是用于byte-oriented的机器。已经很少用了,有些机器支持TYPE L 8其实等价于TYPE I
有一个逻辑字节的概念,于是就有了logical byte size的概念,它不一定是8,logical byte size不一定与transfer byte size相同,如果不同,那么将多个logical bytes紧密的拼接起来,然后在后面加上以恶padding以凑成合适的若干个transfer byte。接受方利用自己的特点以及发送来的数据的logical byte size,以及transfer byte size将数据取出来,然后转换成自己的合适的logical byte size.
例子:
(1)发送36bit的一个floating point数字到另一方,logical byte size=36,transfer byte size为32bit,那么就用2个transfer byte乘放这个logical byte,然后进行padding。
(2)发送双方都是36bit 的word size, 可看成其logical byte size=36, transfer byte size=8的话,他们就将2个logical byte用 9个transfer byte传输。
说白了就是便于双方知道怎么对发送来的字节流进行解码,找出正确的数据。
5. Format control
本内容主要是针对接受方要打印发来的文件为目的的。所以接受方要知道你的文件里使用了什么格式的控制符,要怎么处理这些控制符去打印。
Text文件传输3种目的,立即被print, 存储起来以后处理,当时就处理。不管怎么样吧,你最好告诉我你到底用的什么样的换行字符,以及其他的移动符,用什么控制你的vertical format,这样我好处理。对于ASCII和EBCDIC两种type,有个参数用来指定其使用的vertical format control的。有三种:
(1) NON PRINT 非打印
格式: TYPE A N 或者 TYPE E N
如果不指定format control参数,这是默认的。及文件中不会包含垂直格式信息,如果接受方要打印文件,就使用默认的行距和边界参数值。一般来说,这种格式的接受方不会打印文件,而是要将文件保存。
(2) TELNET FORMAT CONTROLS
文件中包含ASCII/EBCDIC格式的vertical format controls, i.e. CR, LF, NL, VT, FF, CRLF代表End-of-line。
(3) CARRIAGE CONTROL (ASA)
文件包含ASA(FORTRAN)的vertical format controls,
blank 走纸一行
0 走纸两行
1 走纸到下页顶
+
不移动,也就是覆盖打印
文件结构,其实主要取决于文件的存储系统。如source-code文件在IBM Mainframe里采用了固定长度的record存储,而在DEC TOPS-20机上,采用的是CRLF分开的行式的存储格式。所以,并不是所有的系统都是统一的采用了CRLF来保存文本文件的,那么如果你在多个系统之间传文件,就地考虑转换问题,起码让IBM Mainframe上的源文件也能在DEC TOPS-20之间可用吧。所以就的告诉我们的文件的格式。
当将file structure的文件发往一个只支持record structure的机子时,要将文件分成一定的record,如果file structure的文件有End-of-line,那么就可以用这个end-of-line作为record的delimiter,而且这个过程还应该是可逆的。对于TYPE ASCII 来说,end-of-line是CRLF,对于TYPE EBCDIC来说,end-of-line是NL。那么对于非text文件呢?是不是可以采用固定长度的record?
1.File structure
文件本身没有什么结构,就是连续的内容。如果不用STRU命令指定Data structure,默认采用File structure。
终端在处理TYPE ASCII/EBCDIC的文本文件时,必须支持file structure和record structure。
2. record structure
文件内部是具有record的结构,有一系列连续的record构成。
3. page structure
Page structure,其实只应用于TENEX(TOPS-20 operation system),在非TENEX系统,没必要支持Page structure,因此rfc1123里说不支持他。
文件本身的数据不连续,即我们可以认为它含有很多洞,holes, 这些文件称为“random access files”或者“holey files”及,可成为多穴文件,他有个特点,在advanced programming under unix environment 上有介绍,就是这个文件占用的磁盘空间不等于它的文件大小,一个大小文1TB的文件可能只占用了1K的磁盘空间,其余部分都是空洞。如果你夺取这些文件,得空洞部分,读出来的都是0。所以我们在用ftp传输时,没必要传输空洞部分,于是就没必要连续传输一个文件,于是就有了page structure。
我们怎么获知一个文件有多少个空洞,每个空洞的位置以及其大小呢? 只有知道了空洞的部分,才知道非空洞的部分阿,才能用也传输阿,目前没找到解决办法么?
为了描述每个page的大小以及相应的信息,每个page都带有一个header.其中,header带有的fields如下:
(1) header length
(2) page index 是用来表示该page在文件中的位置,而不是传输的page的编号
(3) data length
(4) page type
(5) optional fields
所有这些fields都占用一个logical byte,具体一个logical byte多大,就要看TYPE L n中n的值了。
3.4 transmission modes
所有的传输必须要讲EOF传输出去,EOF的表示形式:
1. 如果Data structure是record structure, 可以用EOR标记表示EOF,显式的。
2. 如果是page structure,可以用page header中page type field = last page来表示结束
3. 如果是file structure呢?还不知道。
4. 如果采用了Block 的传输模式呢,不管采用什么data structure,可以在block的descriptor里面标记最后一个block。
5. 如果采用了compressed 的传输模式呢,不管采用什么data structure,可以使用一个2字节的control code来表示EOF, control code中的descriptor与block 里的descriptor格式一样。
那么此时看来唯一需要关闭连接这种隐式的表示EOF的方法的情况就是:
Stream传输模式+ file structure。
发送接受方需要根据自己存储系统使用的representation type以及data structure和传输的方法来进行一定的转换。比如,IBM MainFrame采用record structure来保存source-code文件,如果另一方不采用该格式,那么发送时就不能将end-of-record作为数据发送:
1. 如果采用stream mode, 就应该将end-of-record字符转换成一个2自己控制字符来表示。
2. 如果采用block mode或者compressed mode, 就只需在block 或者compressed mode descriptor里面用一个bit来表示end-of-record。
如果不采用record structure, 对于SCII/EBCDIC文件中的end-of-line:
1. 如果是ASCII文件,就转换为CRLF
2. 如果是EBCDIC文件,就转换为NL
上述转换都需要cost,所以如果是相同的两个系统传输数据,那么建议采用二进制的type,和stream的传输模式。
数据以字节流传输。对representation type没有限制;可以使用record structure,别的structure也是可以的。
在记录结构文件中,EOR和EOF将分别用两个字节的控制码表示。第一个字节都是同样的escape字符,即全一。第二个字节中,EOR将低位置一,其他位置 零;EOF则是将第二低位置一;也就是这个字节对于EOR来说是1,对于EOF来说是2。EOR和EOF可能在传输结束时通过使最低两为都置一来同时指定(就是值3)。如果想发送escape字符,即向发送一个全一的数据字节,要在第二个字节再重复一次,既要发送两遍。
如果结构是文件结构,则使用关闭主机连接来指示EOF,传输的所有数据字节就是原始字节。这明显就是stream mode在传输file structure的文件时的一个缺点。不过用stream mode传file structure就只能这样。
文件以连续的带有header的block来传输。header包括一个byte count和descriptor。byte count域指示了数据块整个长度,由此可以算出下一数据块的开始位置(没有填充位)。Descriptor(描述码)定义了:这是整个文件的最后一块(EOF),这是整个记录的最后一块(EOR),这个block是一个restart mark marker重开始标记(即这个块是一个标记,可以看作一个书签,接受方将其保存,以后想要重新传递时,可以将一个书签发给server,从而server就知道从哪里开始传递了),或者suspected errors in data block即被怀疑的数据(也就是被怀疑在传输中可能不可靠的数 据)。最后的描述符不是FTP错误控制的一部分。它用来在站点间交换指定类型的数据(比如地震或天气数据)而且简略本地错误(比如磁带读错误)。记录结构 可以在这种模式下使用,而且可以用任何表示类型。
头包括3个字节。在这24位的头信息中,低16位表示字节记数,高8位表示描述符。
块头
+----------------+----------------+----------------+
| 描述符 | 字节记数 |
| 8 bits |
16 bits |
+----------------+----------------+----------------+
描述符字节由各个标志位组成。指定了4个描述码,每一个描述码为描述符的十进制值。描述码 意义
128 数据块结束是EOR
64 数据块结束是EOF
32 怀疑数据块有错
16 数据块是重开始标志
通过对不同的标志位置一,每个数据块可以使用不同的描述符组合。
重开始标志是在数据流中的8位整数,表示在控制连接中使用的可打印字符(比如,缺省的NVT-ASCII)。在重开始标志中不能使用
例如,要传输6个字符标记,应该按如下发送:
+--------+--------+--------+
|描述符| 字节记数 |
| = 16 |
= 6 |
+--------+--------+--------+
+--------+--------+--------+
| 标记 | 标记 | 标记 |
| 8 位 | 8 位 | 8 位
|
+--------+--------+--------+
+--------+--------+--------+
| 标记 | 标记 | 标记 |
| 8 位 | 8 位 | 8 位
|
+--------+--------+--------+
数据被压缩,压缩的方法是将重复的字节用一个字节表示。将重复的filled bytes用一个filled byte表示。
需要传递的数据包括:
1. Regular data, 即未被压缩的数据(它们不能被压缩)
2. Compressed data, 被压缩的数据,包括replications(重复性数据)以及filler(填充字节)
3. Control information,即控制字节
下面是格式 :
(1) regular data:
字节串:
1 7 8 8
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|0| n
| | d(1)
| ... | d(n)
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
^ ^
|---n个字节---|
n字节的字节串d(1),...,d(n) 数n必须为正。
(2) compressed replicated byte
为了压缩n字节的复本,下面两个字节要发送:
复制字节:
2
6 8
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
|1 0| n
| | d
|
+-+-+-+-+-+-+-+-+ +-+-+-+-+-+-+-+-+
表示有n个重复的字节d。
(3) filler string
一串长度n的填充字节可以压缩成一个字节,填充字节与表示类型有关。如果类型是ASCII或EBCDIC,填充字节是
填充字节:
2
6
+-+-+-+-+-+-+-+-+
|1 1| n
|
+-+-+-+-+-+-+-+-+
表示有n个填充字节。
(4) control information由2个字节构成,转义序列由两个字节组成,第一个字节为转义字节(全0)第二个字节包括块模式中定义的描述码。这里的描述码与块模式中的描述码意义相同,并对后面的字节串有效。压缩模式适用于在传输大数据时以较小的CPU代价换来一定的网络带宽。最适合用在减少RJE主机产生的打印文件大小。
3.5 Error recovery and restart
这里并没有提供是否在传输中存在丢失字节或者数据包混乱的方法。这个级别的错误由TCP控制。但必须提供一个重开始的方法来应对系统错误(包括主机、FTP过程、或网络的失败)。
重开始过程只定义在块模式和压缩模式下。它要求数据发送者在数据流中插入一个特殊的标记。这个标记信息只对发送方有意义,但必须由缺省或协商的控制连接语 言(ASCII或EBCDIC)中的可打印字符组成。标记要表示一个位记数,一个记录记数,或者可以表示数据检查点的信息。数据的接收方,如果要实现重开 始过程,将用此标记指定数据位置,并将此信息返回给用户。
系统失败的情况下,用户可以用标记的位置信息重新开始传送过程。下面的例子演示了重开始过程的使用。
数据的发送方在数据流中的适当的位置插入了一个标记块。接收主机在它的文件系统中标记对应的数据点,并直接或用110号控制连接响应(取决于发送方是谁) 向用户传达最后的标记信息。在系统失败时,用户或控制过程使用重开始命令并以标记信息为其参数来重开始传输。重开始命令通过控制连接传输,后面跟上系统失 败时正在执行的命令(比如RETR,STOR或LIST)。
3.2 Establish data connections
有2种data connection的建立方法:
1. Active mode 最终由server主动连接client的数据端口建立数据连接, server主动
2. Passive mode 最终由client主动连接server的数据端口建立数据连接, server被动
S: server
C: client
Ps: port of server
Pc: port of client
Active mode的顺序:
1. C 通过自己某端口连接S的21端口建立control connection
2. C打开自己某个数据端口Pc,然后listen on it.
3. C 通过control connection发送port x,x,x,x命令将IP地址与端口Pc发给S
4. S 以自己的20端口建立连接连向C所制定的IP地址与PC端口
Passive mode的顺序:
1. C 通过自己某端口连接S的21端口建立control connection
2. C 向S发送PASV命令,告诉S要采用passive模式
3. S自己选择一个数据端口PS,打开并listen
4. S 将地址和端口PS做成PASV的response格式发给C
5. C自己选择一个数据端口Pc用来建立到S的Ps的连接
连接的关闭一般都是由Server管理的,但是有例外,就是当client发送数据的时候,可以用关闭连接的方式来表示传输的完毕。那么server端在如下情况下可以关闭连接:
1. Server发送完了数据,并且要通过关闭连接来表示EOF
2. Server收到了client发送的ABORT命令
3. Client端通过某命令将Port specification改变
4. Control connection被关闭了
5. 不能恢复的错误发生后
4 file transfer functions
4.1 ftp commands
Server可能不能同时处理data connection和control connection, 所以为了召唤server来处理control connection 中的ftp commands,又由于我们的control connection使用了telnet的协议,所以需要做一下操作,主要是使用telnet的一些功能(当然对于有些server没必要这样) :
1. User 向telnet stream中插入telnet的Interrupt Process (IP) signal
2. User 发送telnet 的Synch signal
3. User 发送ftp commands
4. Server 在收到telnet 的IP后,扫描telnet stream来接收exactly one ftp command
ftp commands主要分为三类:
1. Access control
commands
USER
PASS
ACCT
CWD
CDUP
SMNT
REIN
QUIT
2. Transfer parameter
commands
PORT
PASV
TYPE
STRU
MODE
3. ftp service
commands
RETR
STOR
STOU
ALLO
REST
RNFR
RNTO
ABOR
DELE
RMD
MKD
PWD
LIST
NLST
SITE
SYST
STAT
HELP
NOOP
4.2 ftp replies
三个digits, 其含义如下:
1. Digit 1 用来表示命令是否成功执行
2. Digit 2用来表示命令的具体范畴,比如,如果出错了,那么大体的范围是什么呢?是文件系统错误,还是与登陆相关的错误
3. Digit 3 是详细的错误,细的分类,与1,2结合才有意义。
5.Declarative specifications
5.1 minimum implementation
至少要支持:
TYPE – ASCII NO PRINT
MODE - stream
STRUCTURE - File, Record
COMMANDS – USER QUIT PORT TYPE, MODE, STRU, RETR, STOR, NOOP
默认值:
TYPE: ASCII NO PRINT
MODE: stream
STRU: File
5.2 connections
只有user-pi才能主动要求使用非default的端口。见port和pasv命令的使用和passive和active mode。
有client 在两个server之间传递数据的流程:
User-PI - Server A User-PI - Server B
------------------ ------------------
C->A : Connect C->B : Connect
C->A : PASV
A->C : 227 Entering Passive Mode. A1,A2,A3,A4,a1,a2
C->B : PORT A1,A2,A3,A4,a1,a2
B->C : 200 Okay
C->A : STOR C->B : RETR
B->A : Connect to HOST-A, PORT-a
Server在和user之间传递万数据之后,不管你server是要关闭data connection还是要留着它,你都要给user一个reply。
命令和参数的大小写无所谓。
5.3 commands
主要是各个commands的格式。
The following are the FTP commands:
USER
PASS
ACCT
CWD
CDUP
SMNT
QUIT
REIN
PORT
PASV
TYPE
STRU
MODE
RETR
STOR
STOU
APPE
ALLO
[
REST
RNFR
RNTO
ABOR
DELE
RMD
MKD
PWD
LIST [
NLST [
SITE
SYST
STAT [
HELP [
NOOP
The syntax of the above argument fields (using BNF notation
where applicable) is:
ASCII code 33 through 126
| E [
| I
| L
5.4 sequence of commands and replies
在连接上server后,一般server都会给一个greeting。
有时server会有一些spontaneous replies要发给各个client,它必须将这些内容放到下一个reply里面发送。比如“the server will shut down”
余下的内容就是各个命令有可能遇到的replies的列表:
Connection Establishment
120
220
220
421
Login
USER
230
530
500, 501, 421
331, 332
PASS
230
202
530
500, 501, 503, 421
332
ACCT
230
202
530
500, 501, 503, 421
CWD
250
500, 501, 502, 421, 530, 550
CDUP
200
500, 501, 502, 421, 530, 550
SMNT
202, 250
500, 501, 502, 421, 530, 550
Logout
REIN
120
220
220
421
500, 502
QUIT
221
500
Transfer parameters
PORT
200
500, 501, 421, 530
PASV
227
500, 501, 502, 421, 530
MODE
200
500, 501, 504, 421, 530
TYPE
200
500, 501, 504, 421, 530
STRU
200
500, 501, 504, 421, 530
File action commands
ALLO
200
202
500, 501, 504, 421, 530
REST
500, 501, 502, 421, 530
350
STOR
125, 150
(110)
226, 250
425, 426, 451, 551, 552
532, 450, 452, 553
500, 501, 421, 530
STOU
125, 150
(110)
226, 250
425, 426, 451, 551, 552
532, 450, 452, 553
500, 501, 421, 530
RETR
125, 150
(110)
226, 250
425, 426, 451
450, 550
500, 501, 421, 530
LIST
125, 150
226, 250
425, 426, 451
450
500, 501, 502, 421, 530
NLST
125, 150
226, 250
425, 426, 451
450
500, 501, 502, 421, 530
APPE
125, 150
(110)
226, 250
425, 426, 451, 551, 552
532, 450, 550, 452, 553
500, 501, 502, 421, 530
RNFR
450, 550
500, 501, 502, 421, 530
350
RNTO
250
532, 553
500, 501, 502, 503, 421, 530
DELE
250
450, 550
500, 501, 502, 421, 530
RMD
250
500, 501, 502, 421, 530, 550
MKD
257
500, 501, 502, 421, 530, 550
PWD
257
500, 501, 502, 421, 550
ABOR
225, 226
500, 501, 502, 421
Informational commands
SYST
215
500, 501, 502, 421
STAT
211, 212, 213
450
500, 501, 502, 421, 530
HELP
211, 214
500, 501, 502, 421
Miscellaneous commands
SITE
200
202
500, 501, 530
NOOP
200
500 421
6.State diagram
列出了几个简单的命令的user发送,等待server的reply的过程。
B表示Begin
W表示wait for reply
S表示success
F表示fail
E表示error
数字1,2,3,4,5分别表示第一个digit为这些数字的reply系列。
这里就不一一列出了。
7 typical ftp scenario
列出了一个scenario。