上文说过,一旦FTP数据发送双方建立控制命令通道和数据传输通道后,双方就可以发送数据。在数据传输中,FTP协议又规定了三种模式,分别是流模式,块模式和压缩模式。
流模式其实就是简单的将要传输的数据比特以一种连续的非结构化的方式在TCP协议的帮助下发送给对方,这里它就是一段数据,不存在包头或字段这类有关数据组织结构的信息。由于被传输的信息是裸数据,没有任何结构化组织,因此发送的准确性完全依赖于传输方和下层协议的稳定性,特别是数据传输完成就得依靠关闭数据通道来表示。
相比于其他两种模式,流模式的特点是效率高,因此在协议的实现中使用广泛。同时它实现简单,并且它将所有要传输的数据进行无差别对待,别管要传输的数据结构如何,它通通将其看做为字节流,因此就能隔离数据结构的复杂性对传输协议实现的影响。由此效率高,实现简单,传输数据复杂性隔离这三个特点使得这种传输模式成为FTP的实现主流。
第二种块模式是指,将要传输的数据切割成长度固定的若干部分,每个部分在发送时使用包头等字段进行封装,使得发送的数据块相互间形成独立的数据包。包头含有三字节字段,分别表示块的长度以及其他相关数据。同时还有一种特别的算法用于对数据块进行追踪,如果数据块传输出现问题算法还能中断或者重启传输流程。
第三种是压缩模式。它使用游程编码对发送数据进行压缩,同时将压缩相关信息以包头字段的方式进行组织,这样对方收到后知道如何对数据进行解压缩,因此压缩模式使用包头 数据体的方式进行数据的组织发送。压缩模式由于实现的复杂性,在FTP协议中很少使用,除非在特定网络条件下需要尽可能减少数据传输量以保证效率和准确性时,该模式才会被采用。
文件传输类似ctrl c和ctrl v,区别在于复制操作是在同一台电脑内将数据从一个目录转移到另一个目录,文件传输是将数据从一台电脑转移到另一台电脑。但这是这一区别产生了一些问题,例如在windows上文本文件的结尾使用CR LF表示,但在Mac系统上文本文件结尾使用CR表示,于是把一个文本文件从Mac拷贝到windows,在文件末尾处就容易出问题,为此FTP协议在传输数据时对数据类型增加了若干考虑。
首先FTP协议把数据分成4种形式加以考虑,一是ASCII,也就是文本为字符形式;二是EBCDIC,这类文件也是字符形式只不过字符来自IBM的EBCDIC字符集;三是图像,这类文件可以不用考虑不同系统之间的区别;四是局部形式,这类文件的特点是,一个字节长度不是由8个比特组成,某些特殊操作系统就有这种特性。我们在实践中只考虑情况一和三,对于情况一,协议要负责把文件结尾的符号根据系统进行修改,情况二中的图像文件不仅仅包括图像,像zip文件这类有同一格式的文件都属于图像。
在传输ASCII文件时,发送方每读取一行内容后就在后面添加字符CR LF,接收方读取到这两个字符组合后知道这是一行结束,然后根据当前所在系统修改,如果接收方是Mac系统,那么就将这两个字符改为CR。由于FTP会对传输数据进行修改,因此在传输一定不能把”图像“类型的文件设置成ASCII类型,要不然”图像“类型文件中的二进制字符被修改后在接收方就无法打开文件。
接下来我们看看协议的数据包格式,特别是控制命令的数据包格式。FTP的控制命令有3种,第一种是接入控制命令,他对应用户登录和认证。第二种是传输控制命令,它用于双方协定数据如何传输,例如设置传输文件的类型,设定主动或被动传输模式;第三是FTP服务命令,这些命令用于发起数据传输,修改或删除文件等等。FTP在传输控制命令时使用Telnet协议,因此命令会以纯字符的形式进行发送,下面我们以列表方式对命令内容进行描述:
命令码 | 命令 | 描述 |
---|---|---|
USER | 用户名 | 在建立连接时发生用户名 |
PASS | 密码 | 在用户登录时提供密码 |
ACCT | 账户类型 | 用于设定用户权限,通常FTP服务器会根据用户名来直接指定其权限 |
CWD | 更改当前目录 | 设定用户登录后对应的服务器目录 |
CDUP | 回到上一层目录 | 将当前目录的上一层目录作为数据传输目录 |
SMNT | 结构挂载 | 让服务器挂载上新的文件系统以便读取特定文件 |
REIN | 重新初始化 | 将连接重启,他会将当前控制参数全部清除,类似于系统重启 |
QUIT | 退出登录 | 当数据发送完毕后用户退出登录 |
接下来我们看看控制命令相关说明:
命令码 | 命令 | 描述 |
---|---|---|
PORT | 建立数据传输端口 | 这个端口将被客户端用于和服务器建立数据传输连接 |
PASV | 消极模式 | 该命令让客户端向服务器主动发起连接 |
TYPE | 文件类型 | 用于设定要传输的文件类型 |
STRU | 文件结构 | 通常情况下该命令不会被使用 |
MODE | 传输模式 | 设定数据如何传输,是以流模式,块模式,还是压缩模式 |
接下来我们看看服务命令的说明:
命令码 | 命令 | 描述 |
---|---|---|
RETR | 获取数据 | 通知服务器向客户端发送文件数据 |
STOR | 存储 | 客户端要发送文件给服务器 |
STOU | 唯一存储 | 要求服务器在确保当前目录下所传输的文件只能有一份 |
APPEN | 内容添加 | 如果当前传输的文件在目录下有同名文件,那么将传输的内容添加到同名文件末尾而不是覆盖同名文件 |
ALLO | 分配内存 | 要求服务器为将要发送的文件提前分配存储空间 |
REST | 重启 | 重启文件传输流程,该命令只用在块传输或压缩传输方式 |
RNFR | 重命名文件 | 指定将要被重命名的文件名 |
RNTO | 文件重命名 | 将指定文件改名为指定名称 |
ABOR | 取消命令 | 通知服务器取消执行上一次发送的命令 |
DELE | 删除 | 通知服务器删除某个文件 |
RMD | 删除目录 | 通知服务器删除整个目录 |
MKD | 创建目录 | 通知服务器创建一个新目录 |
PWD | 显示当前目录 | 通知服务器告知用户当前所在目录 |
LIST | 列表 | 获得当前目录的所有文件名以及文件相关信息例如修改时间等 |
NLST | 命名列表 | 仅仅获得当前目录下的文件名 |
SYST | 系统 | 要求服务器返回它所在的操作系统信息 |
STAT | 状态 | 要求服务器返回指定文件的当前状态或是当前数据传输的状态 |
HELP | 帮助 | 要求服务器返回帮助信息以便客户端决定如何使用服务器 |
NOOP | 无操作 | 该命令表示什么操作都不做,服务器会返回”OK"命令从而确保连通正常 |