标题：tftp
目的
TFTP是一个传输文件的简单协议，它基于UDP协议而实现，但是我们也不能确定有些TFTP协议是基于其它传输协议完成的。此协议设计的时候是进行小文件传输的。因此它不具备通常的FTP的许多功能，它只能从文件服务器上获得或写入文件，不能列出目录，不进行认证，它传输8位数据。传输中有三种模式：netascii，这是8位的ASCII码形式，另一种是octet，这是8位源数据类型；最后一种mail已经不再支持，它将返回的数据直接返回给用户而不是保存为文件。
概况
任何传输起自一个读取或写入文件的请求，这个请求也是连接请求。如果服务器批准此请求，则服务器打开连接，数据以定长512字节传输。每个数据包包括一块数据，服务器发出下一个数据包以前必须得到客户对上一个数据包的确认。如果一个数据包的大小小于512字节，则表示传输结束。如果数据包在传输过程中丢失，发出方会在超时后重新传输最后一个未被确认的数据包。通信的双方都是数据的发出者与接收者，一方传输数据接收应答，另一方发出应答接收数据。大部分的错误会导致连接中断，错误由一个错误的数据包引起。这个包不会被确认，也不会被重新发送，因此另一方无法接收到。如果错误包丢失，则使用超时机制。错误主要是由下面三种情况引起的：不能满足请求，收到的数据包内容错误，而这种错误不能由延时或重发解释，对需要资源的访问丢失（如硬盘满）。TFTP只在一种情况下不中断连接，这种情况是源端口不正确，在这种情况下，指示错误的包会被发送到源机。这个协议限制很多，这些都是为了实现起来比较方便而进行的。
特点
因为TFTP使用UDP，而UDP使用IP，IP可以还使用其它本地通信方法。因此一个TFTP包中会有以下几段：本地媒介头，IP头，数据报头，TFTP头，剩下的就是TFTP数据了。TFTP在IP头中不指定任何数据，但是它使用UDP中的源和目标端口以及包长度域。由TFTP使用的包标记（TID）在这里被用做端口，因此TID必须介于0到65,535之间。对它的初始化我们在后面讨论。TFTP头中包括两个字节的操作码，这个码指出了包的类型，下面我们看看大体上的TFTP包格式，相关的内容我们在后面的章节中进行讨论。
---------------------------------------------------
| Local Medium | Internet | Datagram | TFTP |
---------------------------------------------------
图3-1: 包头次序
初始连接
初始连接时候需要发出WRQ（请求写入远程系统）或RRQ（请求读取远程系统），收到一个确定应答，一个确定可以写出的包或应该读取的第一块数据。通常确认包包括要确认的包的包号，每个数据包都与一个块号相对应，块号从1开始而且是连续的。因此对于写入请求的确定是一个比较特殊的情况，因此它的包的包号是0。如果收到的包是一个错误的包，则这个请求被拒绝。创建连接时，通信双方随机选择一个TID，因为是随机选择的，因此两次选择同一个ID的可能性就很小了。每个包包括两个TID，发送者ID和接收者ID。这些ID用于在UDP通信时选择端口，请求主机选择ID的方法上面已经说过了，在第一次请求的时候它会将请求发到TID 69，也就是服务器的69端口上。应答时，服务器使用一个选择好的TID作为源TID，并用上一个包中的TID作为目的ID进行发送。这两个被选择的ID在随后的通信中会被一直使用。下例是一个写入的例子，其中WRQ，ACK和DATA代表写入请求，确认和数据。
相关应用
1． 主机A向主机B发出WRQ，其中端口为69
2． B机向A机发出ACK，块号为0，包括B和A的TID
此时连接建立，第一个数据包以序列号1从主机开始发出。以后两台主机要保证以开始时确定的TID进行通信。如果源ID与原来确定的ID不一样，这个包会被认识为发送到了错误的地址而被抛弃。错误的包是被发送到正确端口的，但是包本身有错误。设想发送方发出一个请求，这个请求在网络的那个设备中被复制成两个包，接收方先后接收到两个包。接收方会认为为这是两个独立的请求，会返回两个应答。当这两个应答其中之一被接收到时，连接已经建立。第二个应答再到达时，这个包会被抛弃，而不会因为接收到第二个应答包而导致第一个建立的连接失败。
5． TFTP包
TFTP支持五种类型的包，我们在以上已经说明这五种类型的包：
opcode operation
1．Read request (RRQ)
2．Write request (WRQ)
3．Data (DATA)
4．Acknowledgment (ACK)
5．Error (ERROR)
包头中包括了这个包所指定的操作码。
2．bytes string 1 byte string 1 byte
------------------------------------------------
| Opcode | Filename | 0 | Mode | 0 |
------------------------------------------------
Figure 5-1: RRQ/WRQ包
RRQ和WRQ包（代码分别为1和2）的格式如上所示。文件名是NETASCII码字符，以0结束。而MODE域包括了字符串"netascii"，"octet"或"mail"，名称不分大小写。接收到NETASCII格式数据的主机必须将数据转换为本地格式。OCTET模式用于传输文件，这种文件在源机上以8位格式存储。假设每个机器都存在一个8位的格式，这样的假设是最一般的。比如DEC-20，这是一种36位机，我们可以假设它是4个8位外加另外4位而构成。如果机器收到OCTET格式文件，返回时必须与原来文件完全一样。在使用MAIL模式时，用户可以在FILE处使用接收人地址，这个地址可以是用户名或用户名@主机的形式，如果是后一种形式，允许主机使用电子邮件传输此文件。如果使用MAIL类型，包必须以WRQ开始，否则它与NETASCII完全一样。我们的讨论建立在发送方和接收方都在相同模式的情况下，但是双方可以以不同的模式进行传输。例如一个机器可以是一台存储服务器，这样一台服务器需要将NETASCII格式转换为自己的格式。另外，我们可以设想DEC-20这种机器，它使用36位字长，用户这边可以使用特殊的机制一次读取36位，而服务器却可以仍然使用8位格式。在这两种情况下，我们看到了两台机器使用不同格式的情况。可以在两台主机间定义其它的传输方式，但是定义要小心，因为这种传输方式不为人知，而且也没有权威机构为其指定名称或定义它的模式。
2．bytes 2 bytes n bytes
----------------------------------
| Opcode | Block # | Data |
----------------------------------
Figure 5-2: DATA包
数据在数据包中传输，其格式如上图所示。数据包的OP码为3，它还包括有一个数据块号和数据。数据块号域从1开始编码，每个数据块加1，这样接收方可以确定这个包是新数据还是已经接收过的数据。数据域从0字节到512字节。如果数据域是512字节则它不是最后一个包，如果小于512字节则表示这个包是最后一个包。除了ACK和用于中断的包外，其它的包均得到确认。发出新的数据包等于确认上次的包。WRQ和DATA包由ACK或ERROR数据包确认，而RRQ数据包由DATA或ERROR数据包确认。下图即是一个ACK包，操作码为4。其中的包号为要确认的数据包的包号。
2．bytes 2 bytes
---------------------
| Opcode | Block # |
---------------------
Figure 5-3: ACK包
WRQ数据包被ACK数据包确认，WRQ数据包的包号为0。
2．bytes 2 bytes string 1 byte
-----------------------------------------
| Opcode | ErrorCode | ErrMsg | 0 |
-----------------------------------------
Figure 5-4: ERROR包
一个ERROR包，它的操作码是5，它的格式如上所示。此包可以被其它任何类型的包确认。错误码指定错误的类型。错误的值和错误的意义在附录中。错误信息是供程序员使用的。
正常终止
传输的结束由DATA数据标记，其包括0-511个字符。这个包可以被其它数据包确认。接收方在发出对最后数据包的确认后可以断开连接，当然，适当的等待是比较好的，如果最后的确定包丢失可以再次传输。如果发出确认后仍然收到最后数据包，可以确定最后的确认丢失。发送最后一个DATA包的主机必须等待对此包的确认或超时。如果响应是ACK，传输完成。如果发送方超时并不准备重新发送并且接收方有问题或网络有问题时，发送也正常结束。当然实现时也可以是非正常结束，但无论如何连接都将被关闭。
早终结
如果请求不能被满足，或者在传输中发生错误，需要发送ERROR包。这仅是一种传输友好的方式，这种包不会被确认也不会被重新传输，因此这种包可能永远不会被接收到。因此需要用超时来侦测错误。
其它相关
I. 附录
包头的次序
2．bytes
----------------------------------------------------------
| Local Medium | Internet | Datagram | TFTP Opcode |
----------------------------------------------------------
TFTP格式
Type Op # 没有包头的格式
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 |
----------------------------------------
读文件的初始连接
1． 主机A发RRQ到A，包括源=A的ID和目的=69
2． 主机B发送DATA，其中包号=1，这个包被传送到A，源=B的ID，目的=A的ID
错误码
Value Meaning
0 未定义，请参阅错误信息（如果提示这种信息的话）
1．文件未找到
2．访问非法
3．磁盘满或超过分配的配额
4．非法的TFTP操作
5．未知的传输ID
6．文件已经存在
7．没有类似的用户
Internet用户数据报头
（TFTP不一定非要在UDP上实现。）
Format
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Source Port | Destination Port |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length | Checksum |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
域的值
Source Port 由传输发起方选择
Dest. Port 由目的地选择（如果是RRQ或WRQ，其值为69）
Length 包括UDP包头的包长度
Checksum 校验码，如果是0，则未使用校验
注意：TFTP将传输标记TID传送给UDP作为源和目的端口
安全问题
因为TFTP没有安全控制机制，因此安全问题应该多加考虑。通常TFTP允许下载数据而不允许上传数据。
内部命令
FTP命令是Internet用户使用最频繁的命令之一，不论是在DOS还是UNIX操作系统下使用FTP，都会遇到大量的FTP内部命令。熟悉并灵活应用FTP的内部命令，可以大大方便使用者，并收到事半功倍之效。
FTP的命令行格式为：ftp-v-d-i-n-g[主机名]，其中
-v显示远程服务器的所有响应信息；
-n限制ftp的自动登录，即不使用；
.netrc文件；
-d使用调试方式；
-g取消全局文件名。
ftp使用的内部命令如下(中括号表示可选项):
1．！[cmd[args>：在本地机中执行交互shell，exit回到ftp环境，如：！ls*
.zip.
2．$macro-ame[args]：执行宏定义macro-name.
3．account[password]：提供登录远程系统成功后访问系统资源所需的补充口令。
4．appendlocal-file[remote-file]：将本地文件追加到远程系统主机，若未指定远程系统文件名，则使用本地文件名。
5．ascii：使用ascii类型传输方式。
6．bell：每个命令执行完毕后计算机响铃一次。
7．bin：使用二进制文件传输方式。
8．bye：退出ftp会话过程。
9．case：在使用mget时，将远程主机文件名中的大写转为小写字母。
10．cdremote-dir：进入远程主机目录。
11．cdup：进入远程主机目录的父目录。
12．chmodmodefile-name：将远程主机文件file-name的存取方式设置为mo
de，如：chmod777a.out。
13．close：中断与远程服务器的ftp会话(与open对应)。
14． cr：使用asscii方式传输文件时，将回车换行转换为回行。
15．deleteremote-file：删除远程主机文件。
16．debug[debug-value]：设置调试方式，显示发送至远程主机的每条命令，如：debup3，若设为0，表示取消debug。
17．dir[remote-dir][local-file]：显示远程主机目录，并将结果存入本地文件local-file。
18．disconnection：同close。
19．formformat：将文件传输方式设置为format，缺省为file方式。
20．getremote-file[local-file]：将远程主机的文件remote-file传至本地硬盘的local-file。
21．glob：设置mdelete，mget，mput的文件名扩展，缺省时不扩展文件名，同命令行的-g参数。
22．hash：每传输1024字节，显示一个hash符号(#)。
23．help[cmd]：显示ftp内部命令cmd的帮助信息，如：helpget。
24．idle[seconds]：将远程服务器的休眠计时器设为[seconds]秒。
25．image：设置二进制传输方式(同binary)。
26．lcd[dir]：将本地工作目录切换至dir。
27． ls[remote-dir][local-file]：显示远程目录remote-dir，并存入本地文件local-file。
28．macdefmacro-name：定义一个宏，遇到macdef下的空行时，宏定义结束。
29．mdelete[remote-file]：删除远程主机文件。
30．mdirremote-fileslocal-file：与dir类似，但可指定多个远程文件，如：mdir*.o.*.zipoutfile。
31．mgetremote-files：传输多个远程文件。
32．mkdirdir-name：在远程主机中建一目录。
33．mlsremote-filelocal-file：同nlist，但可指定多个文件名。
34．mode[modename]：将文件传输方式设置为modename，缺省为stream方式。
35．modtimefile-name：显示远程主机文件的最后修改时间。
36．mputlocal-file：将多个文件传输至远程主机。
37．newerfile-name：如果远程机中file-name的修改时间比本地硬盘同名
文件的时间更近，则重传该文件。
38．nlist[remote-dir][local-file]：显示远程主机目录的文件清单，并存入本地硬盘的local-file。
39．nmap[inpatternoutpattern]：设置文件名映射机制，使得文件传输时，文件中的某些字符相互转换，如：nmap$1.$2.$3[$1，$2].[$2，$3]，则传输文件a1.a2.a3时，文件名变为a1，a2。该命令特别适用于远程主机为非UNIX机的情况。
40．ntrans[inchars[outchars>：设置文件名字符的翻译机制，如ntrans　1R，则文件名LLL将变为RRR。
41．openhost[port]：建立指定ftp服务器连接，可指定连接端口。
42．passive：进入被动传输方式。
43．prompt：设置多个文件传输时的交互提示。
44．proxyftp-cmd：在次要控制连接中，执行一条ftp命令，该命令允许连接两个ftp服务器，以在两个服务器间传输文件。第一条ftp命令必须为open，以首先建立两个服务器间的连接。
45．putlocal-file[remote-file]：将本地文件local-file传送至远程主机。
46．pwd：显示远程主机的当前工作目录。
47.quit：同bye，退出ftp会话。
48．quotearg1，arg2…：将参数逐字发至远程ftp服务器，如：quotesyst.
49．recvremote-file[local-file]：同get。
50．regetremote-file[local-file]：类似于get，但若local-file存在，则从上次传输中断处续传。
51．rhelp[cmd-name]：请求获得远程主机的帮助。
52．rstatus[file-name]：若未指定文件名，则显示远程主机的状态，否则显示文件状态。
53．rename[from][to]：更改远程主机文件名。
54．reset：清除回答队列。
55．restartmarker：从指定的标志marker处，重新开始get或put，如：restart130。
56．rmdirdir-name：删除远程主机目录。
57．runique：设置文件名唯一性存储，若文件存在，则在原文件后加后缀..1，.2等。
58．sendlocal-file[remote-file]：同put。
59．sendport：设置PORT命令的使用。
60．sitearg1，arg2…：将参数作为SITE命令逐字发送至远程ftp主机。
61．sizefile-name：显示远程主机文件大小，如：siteidle7200。
62．status：显示当前ftp状态。
63．struct[struct-name]：将文件传输结构设置为struct-name，缺省时使用stream结构。
64．sunique：将远程主机文件名存储设置为唯一(与runique对应)。
65．system：显示远程主机的操作系统类型。
66．tenex：将文件传输类型设置为TENEX机的所需的类型。
67．tick：设置传输时的字节计数器。
68．trace：设置包跟踪。
69．type[type-name]：设置文件传输类型为type-name，缺省为ascii，如：typebinary，设置二进制传输方式。
70．umask[newmask]：将远程服务器的缺省umask设置为newmask，如：umask3。
71．useruser-name[password][account]：向远程主机表明自己的身份，需要口令时，必须输入口令。
72．verbose：同命令行的-v参数，即设置详尽报告方式，ftp服务器的所有响应都将显示给用户，缺省为on.