在项目中udp环境下需要进行文件传输,一种高效的文件传输。文件传输一般会想到FTP 和TFTP,但考虑限制条件,所以采用TFTP。
TFTP是什么?
TFTP是一种简单的文件传输协议。目标是在UDP之上上建立一个类似于FTP的但仅支持文件上传和下载功能的传输协议,所以它不包含FTP协议中的目录操作和用户权限等内容。
与FTP相似,TFTP传输过程中也有传输模式之分,模式的意思是如何解释数据包里的内容,比如是字符串还是二进制等。目前有三种模式:
· l netascii型:一种修改的8bit ascii码
· l octet型:即binary普通的二进制型
· l mail型:过时,不再使用
另外,通讯双方也可以自定义所需的传输模式
TFTP的通信流程
TFTP共定义了五种类型的包格式,格式的区分由包数据前两个字节的Opcode字段区分,分别是:
· l 读文件请求包:Read request,简写为RRQ,对应Opcode字段值为1
· l 写文件请求包:Write requst,简写为WRQ,对应Opcode字段值为2
· l 文件数据包:Data,简写为DATA,对应Opcode字段值为3
· l 回应包:Acknowledgement,简写为ACK,对应Opcode字段值为4
· l 错误信息包:Error,简写为ERROR,对应Opcode字段值为5
1、由客户端发起读文件/写文件的请求,同时可以进行请求连接
2、服务器监听到请求,打开连接,并向客户端发送文件,以每个定长为512字节的块进行发送。每个数据包包含一个数据块,在发送下一个包的时候必须被客户端确认回应一个回应包。
3、当发现某个数据包小于512个字节,说明传输终止。
4、如果出现网络丢包,收件方(客户端)会超时,并且重传最后的接收包(可以是数据包或者回应包),因此这将可以让发送者重新发送丢失包。当之前的包已经接受成功之后,发送者只需要保持一个重传包。注意 发送者 要做的事情:发送数据,接受 回应包;接受者要做的:发送回应包,接受数据。如下图所示:
读请求和写请求的回应是不一样的下图是读请求
有许多的错误会造成连接中断.
1、发送错误的包,这个包没有回应,也没有重发,(例如,TFTP服务器或者客户端会因为收到错误的信息终止)这样导致对方接受不到。所以引入了超时机制。通常错误由3种情况导致:
(1)、不能满足请求的内容(例如:文件找不到,不允许接入,或者用户不存在)
(2)、由于网络延迟或者重置导致正在接收的包无法解析(例如包的格式不正确)
(3)、必须访问资源丢失(例如磁盘满了,或者传输过程中拒绝访问)
TFTP意识到仅有一个错误条件是不会导致中断的,那就是接收包的源端口不正确。在这种情况下会向原始的服务器发一个错误包。
为了简单的实现,TFTP协议非常的有限。例如:固定大小的块可以使得分配空间更直接,在锁定等待回应包可以方便控制流并且不需要重排接到的数据包
TFTP的具体包结构
因为TFTp是设计在udp上层的协议,并且是报文是基于网络协议,属于数据包将拥有一个网络包头,报文头,和TFTP头
另外数据包有可能还有其他的头(例如LNI,ARPA头等等)来允许他们通过本地的传输媒体。下面的表表示了一个包包含的内容: local medium header, if used, Internet header,
Datagram header, TFTP header, followed by the remainder of the TFTP
Packet.
TFTP不需要制定任何的网络头的值。另外报文头数据源和目标端口字段用于TFTP,长度字段但应tftp包的大小。用于TFTP的传输id(tid)会传到报文层当作端口使用,因此必须是0~65535(16位,2个字节)
---------------------------------------------------
| Local Medium | Internet | Datagram | TFTP |
---------------------------------------------------
Figure 3-1: Order of Headers
TFTP支持5中操作类型的数据:
opcode operation
1 Read request (RRQ) 读文件请求
2 Write request (WRQ) 写文件请求
3 Data (DATA) 数据
4 Acknowledgment (ACK) 确认包
5 Error (ERROR) 错误
TFTP的请求包。如下图
2 bytes string 1 byte string 1 byte
------------------------------------------------
| Opcode | Filename | 0 | Mode | 0 |
------------------------------------------------
Figure 5-1: RRQ/WRQ packet
上述协议中
Opcode 操作码
Filename:netascii的文件字节序号,0表示终止
Mode:类型主要 可以是 "netascii", "octet", or "mail" (这几个单词的字母不区分大小写)
数据包格式:
2 bytes 2 bytes n bytes
----------------------------------
| Opcode | Block # | Data |
----------------------------------
Figure 5-2: DATA packet
Block# 从1开始,每一个新包自加。此限制,允许程序使用一个单一的数字来区分的新数据包之间的重复。每一个块的定长为512 (2^9),如果出现某一块长度部位512,那就表示数据传输完成,终止传输。
除了ACK和用于中断的包外,其它的包均得到确认。发出新的数据包等于确认上次的包。WRQ和DATA包由ACK或ERROR数据包确认,而RRQ数据包由DATA或ERROR数据包确认。
ACK包
2 bytes 2 bytes
---------------------
| Opcode | Block # |
---------------------
Figure 5-3: ACK packet
错误包结构
2 bytes 2 bytes string 1 byte
-----------------------------------------
| Opcode | ErrorCode | ErrMsg | 0 |
-----------------------------------------
Figure 5-4: ERROR packet
附录:
Order of Headers(头顺序)
2 bytes
----------------------------------------------------------
| Local Medium | Internet | Datagram | TFTP Opcode |
----------------------------------------------------------
TFTP Formats(TFTP格式)
Type Op # Format without header
2 bytes string 1 byte string 1 byte
-----------------------------------------------
RRQ/ | 01/02 | Filename | 0 | Mode | 0 |
WRQ -----------------------------------------------
2 bytes 2 bytes n bytes
---------------------------------
DATA | 03 | Block # | Data |
---------------------------------
2 bytes 2 bytes
-------------------
ACK | 04 | Block # |
--------------------
2 bytes 2 bytes string 1 byte
----------------------------------------
ERROR | 05 | ErrorCode | ErrMsg | 0 |
----------------------------------------
初始化一个读文件的连接
初始化连接协议
一旦发送请求(WRQ 写文件请求或者 RRQ读文件请求),传输就已经建立,并且收到写的回应包,或读取第一个数据,的肯定答复。一般说回应包会包含已经回应的数据包的块序号。每一个数据包都和他的块序号关联,块序号从1开始,顺序增加。在特殊的情况下块序号是0,即当写请求的相应包是一个确认包的时候(通常,只要确认包是确认的数据包,确认包会包含被确认数据的块序号)。如果回应是一个错误包,请求会被拒绝。
为了建立连接,连接的每一段都会为自己在传输期间选则传输id(tid)。连接的tid是随机生成的,所以在一个过程中同时出现两个相同的tid的概率是非常少的。每一个包都包含两个tid,一个是源tid,一个是目标tid。这两个tid是用来支持udp(或者其他报文协议)作为源端口和目标端口。在响应请求的,正常情况操作下,服务器使用自己的TID作为源TID,而选择上一条请求消息的Tid作为目标TID。这两个TId作为接下来的传输。
例如:
1.主机A向主机B发出WRQ,其中端口为69
2. B机向A机发出ACK,块号为0,包括B和A的TID
错误码
值 表示意思
0 未定义Not defined, see error message (if any).
1 文件找不到File not found.
2 拒绝访问Access violation.
3 磁盘满了或者超出了可分配空间Disk full or allocation exceeded.
4 非法TFTP操作Illegal TFTP operation.
5 传输ID未知Unknown transfer ID.
6 文件不存在File already exists.
7 没有该用户No such user.
TFTP总结
整体上来说,TFTP的一个重要特点就是简单及易于实现,这也是设计TFTP协议的一个初衷。
优点:
· l 每个数据包大小固定,这样在内存分配处理的时候比较直接
· l 实现简单
· l 每个数据包都有确认机制,可以实现一定程度的可靠性
缺点:
· l 传输效率不高
· l 滑动窗口机制太简单,并且该窗口仅有一个包的大小
· l 超时处理机制并不完善,RFC1350并没有给出详细的处理机制说明