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 的交互序列。

TFTP RRQ 会话流程 TFTP RRQ 会话流程(PXE 文件读取) PXE 客户端 TFTP 服务器 ① RRQ (Opcode=1, "pxelinux.0", octet) ② DATA (Opcode=3, Block#=1, 512B) ③ ACK (Opcode=4, Block#=1) ④ DATA (Opcode=3, Block#=2, 512B) ⑤ ACK (Opcode=4, Block#=2) ⑥ DATA (Opcode=3, Block#=N, 200B < 512) ⑦ ACK (Opcode=4, Block#=N) → 会话结束

流程说明

  1. RRQ 请求:客户端向服务器 UDP 69 端口发送 RRQ 报文,请求文件 pxelinux.0,模式为 octet。
  2. DATA 传输:服务器以 512 字节为一块,依次发送 DATA 报文,块编号从 1 开始递增。
  3. ACK 确认:客户端每收到一个 DATA 包,立即回复 ACK,确认块编号。
  4. 停等循环:服务器必须等待 ACK 到达后才能发送下一个 DATA 包。这是 TFTP 性能瓶颈的核心原因。
  5. 结束条件:当服务器发送的数据包长度 < 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 引导性能调优的主要靶点。