2. TFTP 协议基础:报文格式与包结构分析
TFTP(Trivial File Transfer Protocol,简单文件传输协议)是 PXE 网络引导中最核心的数据传输协议。与 FTP 不同,TFTP 基于 UDP 传输,无认证、无目录浏览功能,设计极其精简。在 PXE 场景中,BIOS/UEFI 固件通过 TFTP 从引导服务器下载 pxelinux.0、vmlinuz、initrd.img 等启动文件。理解 TFTP 报文结构,是后续分析传输瓶颈、优化并发性能的前提。
2.1 TFTP 协议概述
TFTP 定义在 RFC 1350 中,使用 UDP 端口 69。其核心特征包括:
- 无连接:每次传输独立建立会话,无持久连接。
- 停等协议(Stop-and-Wait):发送方每发送一个数据包,必须等待接收方 ACK 确认后才能发送下一个包。
- 固定包长:数据包最大 516 字节(4 字节头部 + 512 字节数据),最后不足 512 字节表示传输结束。
- 五种报文类型:RRQ(读请求)、WRQ(写请求)、DATA(数据)、ACK(确认)、ERROR(错误)。
性能要点:TFTP 的停等机制是 PXE 引导性能瓶颈的根本原因。在高速网络(千兆/万兆)环境下,512 字节的窗口大小导致链路利用率极低,后续章节将重点讨论如何通过并发和 blksize 选项突破这一限制。
2.2 TFTP 报文通用格式
所有 TFTP 报文均采用统一的头部结构,前 2 个字节为操作码(Opcode),后续字段根据操作码不同而变化。
| 字节偏移 | 字段 | 长度(字节) | 说明 |
|---|---|---|---|
| 0-1 | Opcode | 2 | 操作码,标识报文类型(1-5) |
| 2+ | Payload | 可变 | 根据 Opcode 不同,包含文件名、模式、块号或错误信息 |
操作码定义表
| Opcode | 报文类型 | 方向 | 用途 |
|---|---|---|---|
| 1 | RRQ (Read Request) | Client → Server | 客户端请求读取文件 |
| 2 | WRQ (Write Request) | Client → Server | 客户端请求写入文件(PXE 中极少使用) |
| 3 | DATA (Data) | Server → Client | 服务器发送数据块 |
| 4 | ACK (Acknowledgment) | Client → Server | 客户端确认收到数据块 |
| 5 | ERROR (Error) | 双向 | 报告错误 |
2.3 RRQ / WRQ 报文结构
RRQ 和 WRQ 报文结构完全相同,仅在 Opcode 上区分。客户端通过 RRQ 发起文件读取请求,这是 PXE 引导中最频繁使用的报文类型。
2 bytes string 1 byte string 1 byte
+--------+------------+------+------------+------+
| Opcode | Filename | 0 | Mode | 0 |
+--------+------------+------+------------+------+
Opcode = 1 (RRQ) 或 2 (WRQ)
Filename = 请求的文件名,如 "pxelinux.0"
Mode = 传输模式,通常为 "octet"(二进制模式)
字段说明
- Filename:以 NULL 字节(0x00)结尾的 ASCII 字符串,最大长度受 UDP 包限制(通常 512 字节以内)。
- Mode:传输模式字符串,同样以 NULL 结尾。PXE 场景固定使用
octet(二进制模式),netascii(文本模式)不适用于引导文件。 - 选项扩展(RFC 2347):在 Mode 字段之后,可以附加 TLV(类型-长度-值)格式的选项,如
blksize、timeout、tsize。这是性能优化的关键扩展点。
优化切入点:在 RRQ 报文中附加
blksize 1468 选项,可以将数据块大小从 512 字节提升到 1468 字节(以太网 MTU 1500 - UDP/IP 头部开销),减少 ACK 交互次数,提升吞吐量约 3 倍。
2.4 DATA 报文结构
DATA 报文是服务器向客户端传输文件内容的基本单元。每个 DATA 报文携带一个数据块和对应的块编号。
2 bytes 2 bytes up to 512 bytes
+--------+------------+-------------------+
| Opcode | Block # | Data |
+--------+------------+-------------------+
Opcode = 3 (DATA)
Block # = 块编号,从 1 开始递增
Data = 文件内容,长度 0-512 字节
关键规则
- 块编号(Block #):16 位无符号整数,从 1 开始,每发送一个 DATA 包递增 1。编号 0 保留用于 WRQ 的初始 ACK。
- 数据长度:前 512 字节的块满额发送;最后一个块如果不足 512 字节,表示文件传输结束。
- 结束判定:接收方收到一个数据长度 < 512 字节的 DATA 包后,发送 ACK 并关闭会话。
- 重传机制:发送方启动超时定时器,若在超时时间内未收到对应块号的 ACK,则重传该 DATA 包。默认超时通常为 5 秒。
2.5 ACK 报文结构
ACK 报文是 TFTP 停等协议的核心控制报文。客户端每收到一个 DATA 包,必须回复一个 ACK 确认。
2 bytes 2 bytes
+--------+------------+
| Opcode | Block # |
+--------+------------+
Opcode = 4 (ACK)
Block # = 确认的块编号
ACK 确认逻辑
- 客户端收到 Block # = N 的 DATA 包后,回复 ACK Block # = N。
- 服务器收到 ACK Block # = N 后,发送下一个 DATA Block # = N+1。
- 如果服务器收到重复的 ACK(例如网络延迟导致客户端重传 ACK),服务器忽略该 ACK,继续等待正确的 ACK 或超时。
- 对于 RRQ 请求,服务器直接发送 DATA Block # = 1,无需等待 ACK 0。
2.6 ERROR 报文结构
当传输过程中发生错误时,发送 ERROR 报文终止会话。错误码定义在 RFC 1350 中。
2 bytes 2 bytes string 1 byte
+--------+------------+------------+------+
| Opcode | ErrorCode | ErrMsg | 0 |
+--------+------------+------------+------+
Opcode = 5 (ERROR)
ErrorCode = 错误码(0-7)
ErrMsg = 可读的错误描述字符串,以 NULL 结尾
标准错误码表
| ErrorCode | 含义 | PXE 场景常见原因 |
|---|---|---|
| 0 | 未定义错误 | 通用错误 |
| 1 | 文件未找到 | 引导文件路径错误或缺失 |
| 2 | 访问违规 | 权限不足 |
| 3 | 磁盘满或分配超限 | 写请求时磁盘空间不足 |
| 4 | 非法的 TFTP 操作 | 请求了不支持的选项 |
| 5 | 未知传输 ID | UDP 端口不匹配 |
| 6 | 文件已存在 | 写请求时文件已存在 |
| 7 | 无此用户 | 认证失败(极少使用) |
排障提示:PXE 引导失败时,如果客户端显示 "TFTP Error 1: File not found",请检查 TFTP 根目录配置和文件名大小写。PXE 固件通常发送全小写的文件名,而 Linux 文件系统区分大小写。
2.7 TFTP 会话流程(RRQ 读取)
下图展示了 PXE 客户端通过 TFTP 读取引导文件的完整会话流程,包含 RRQ、DATA、ACK 的交互序列。
流程说明
- RRQ 请求:客户端向服务器 UDP 69 端口发送 RRQ 报文,请求文件
pxelinux.0,模式为octet。 - DATA 传输:服务器以 512 字节为一块,依次发送 DATA 报文,块编号从 1 开始递增。
- ACK 确认:客户端每收到一个 DATA 包,立即回复 ACK,确认块编号。
- 停等循环:服务器必须等待 ACK 到达后才能发送下一个 DATA 包。这是 TFTP 性能瓶颈的核心原因。
- 结束条件:当服务器发送的数据包长度 < 512 字节时,客户端回复最后一个 ACK 后会话终止。
2.8 性能关键点:停等协议的开销分析
TFTP 的停等机制在局域网(低延迟)环境下尚可接受,但在以下场景中性能急剧下降:
| 场景 | RTT(往返延迟) | 理论最大吞吐量(512B 块) | 链路利用率(千兆) |
|---|---|---|---|
| 同交换机局域网 | 0.2 ms | ~2.5 MB/s | ~2% |
| 跨三层路由 | 1 ms | ~0.5 MB/s | ~0.4% |
| WAN 链路 | 10 ms | ~50 KB/s | ~0.04% |
优化方向:从表中可以看出,即使在同一交换机内,TFTP 的链路利用率也仅为 2% 左右。后续章节将深入讲解如何通过 blksize 扩展(将块大小提升至 1468 字节)和 并发传输(多会话同时下载不同文件)来突破这一瓶颈。
2.9 本章小结
- TFTP 使用 UDP 69 端口,采用停等协议,每次传输一个 512 字节数据块。
- 五种报文类型:RRQ(读请求)、WRQ(写请求)、DATA(数据)、ACK(确认)、ERROR(错误)。
- RRQ 报文包含文件名和模式字段,支持选项扩展(blksize、timeout、tsize)。
- DATA 报文携带块编号(1-65535)和最多 512 字节数据,最后一块不足 512 字节表示传输结束。
- ACK 报文确认块编号,是停等协议的控制核心。
- ERROR 报文携带错误码和描述信息,用于异常终止会话。
- 停等协议导致链路利用率极低(千兆网络下约 2%),是 PXE 引导性能调优的主要靶点。