3、TFTP协议基础:TFTP与FTP的区别、TFTP报文格式、TFTP的传输模式
聊到网络启动,TFTP 是个绕不开的角色。说白了,它就是 FTP 的「瘦身版」。我刚开始做 PXE 网络装机时,第一反应也是:为啥不用 FTP?后来踩了坑才明白,TFTP 的存在,恰恰是因为 FTP 太「重」了。
3.1 TFTP 与 FTP 的区别
先看一张对比表,这样更直观:
| 对比项 | TFTP | FTP |
|---|---|---|
| 传输层协议 | UDP(端口 69) | TCP(端口 21/20) |
| 连接方式 | 无连接,无会话 | 有连接,有会话管理 |
| 认证机制 | 无(不验证用户名密码) | 有(支持匿名/用户认证) |
| 传输效率 | 高,但不可靠 | 低,但可靠 |
| 适用场景 | 局域网、嵌入式、网络启动 | 广域网、文件管理、大文件传输 |
| 代码复杂度 | 极简(几十行代码可实现) | 复杂(状态机、多线程) |
我个人习惯把 TFTP 理解为「一次性快递」—— 丢过去就不管了,丢了再重发。而 FTP 更像是「挂号信」,每一步都要确认签收。你想想看,在 PXE 启动阶段,客户端连操作系统都没有,哪来的用户认证?哪来的 TCP 协议栈?所以 TFTP 这种「裸奔」的方式反而最合适。
3.2 TFTP 报文格式
TFTP 的报文结构非常简洁。我当年第一次抓包分析时,差点以为抓错了 —— 就这么几个字段?嗯,没错,就是这么简单。
TFTP 报文分为 5 种类型,由操作码(Opcode)区分:
- RRQ(读请求,Opcode=1):客户端请求从服务器读取文件
- WRQ(写请求,Opcode=2):客户端请求向服务器写入文件
- DATA(数据包,Opcode=3):实际传输的文件数据块
- ACK(确认包,Opcode=4):对数据包的确认
- ERROR(错误包,Opcode=5):传输过程中发生错误
报文格式如下(以 RRQ 为例):
2 bytes string 1 byte string 1 byte
+--------+----------+--------+---------+--------+
| Opcode | Filename | 0 | Mode | 0 |
+--------+----------+--------+---------+--------+
Opcode = 1 (RRQ)
Filename = "pxelinux.0"
Mode = "octet" 或 "netascii"
DATA 包的格式稍微复杂一点:
2 bytes 2 bytes n bytes
+--------+----------+---------------+
| Opcode | Block # | Data |
+--------+----------+---------------+
Opcode = 3 (DATA)
Block # = 1, 2, 3, ... (16位无符号整数)
Data = 最多 512 字节
ACK 包更简单:
2 bytes 2 bytes
+--------+----------+
| Opcode | Block # |
+--------+----------+
Opcode = 4 (ACK)
Block # = 被确认的数据块编号
这里有个经典的「锁步协议」机制:客户端发一个 ACK,服务器才发下一个 DATA。说白了就是「你确认一个,我发一个」。这种设计在局域网里够用,但跨网段时延迟会很高。我曾经在跨 VLAN 的 PXE 环境里遇到过,TFTP 传输速度慢得像蜗牛,后来加了 TFTP 代理才解决。
3.3 TFTP 的传输模式
TFTP 支持两种传输模式,这个选择直接影响文件内容:
3.3.1 octet 模式(二进制模式)
这是我最常用的模式。octet 模式把文件当作原始字节流传输,不做任何转换。对于二进制文件(比如内核 vmlinuz、引导加载器 pxelinux.0),必须使用 octet 模式。
举个例子:
# 使用 tftp 客户端以 octet 模式下载文件
tftp> mode octet
tftp> get vmlinuz
octet 模式下,文件内容完全一致,MD5 校验值不会变。我建议所有网络启动场景都默认用 octet 模式,除非你明确知道自己在做什么。
3.3.2 netascii 模式(文本模式)
netascii 模式会做行尾转换。具体来说:
- 发送端:将本地的换行符(\n)转换为 CRLF(\r\n)
- 接收端:将 CRLF 转换回本地的换行符
这个模式在 Unix 和 Windows 之间传输文本文件时有用。但说实话,我在网络启动项目中几乎不用它。为什么?因为 PXE 传输的文件大多是二进制文件,netascii 模式会破坏二进制数据。我曾经见过有人用 netascii 模式传输内核,结果内核启动时直接 panic —— 因为二进制数据被「污染」了。
3.4 知识体系结构图
下面这张图可以帮你快速理清本章的知识脉络:
嗯,到这里 TFTP 的基础内容就差不多了。记住:TFTP 虽然简单,但它是网络启动的基石。很多 PXE 故障,追根溯源都是 TFTP 配置不当导致的。下一节我们会深入 TFTP 的实战配置,到时候再聊具体怎么调优。
- TFTP 基于 UDP,FTP 基于 TCP —— 这是最根本的区别
- TFTP 报文只有 5 种类型,512 字节的数据块是核心
- 网络启动必须用 octet 模式,netascii 模式会破坏二进制文件
- 锁步协议(发一个确认一个)是 TFTP 的可靠性保障,也是性能瓶颈
可可精品资料库