📚 第二章 TCP/IP基础知识
📄 一句话概括

RFC 是编号连续的公开文档,谁都能免费下载——这一点比内容更重要。 同一份规范的头部格式,四十年前和今天完全不同,那就是版本的痕迹。

📝 本节和前面几节的关系

2.2.2 讲的是标准化的思路,这一节讲标准长什么样。 这一节会真拉两份 RFC 对照,一份 1981 年、一份 2022 年。

一、RFC 是什么

三个特征,缺一不可:

特征 含义 为什么重要
编号连续 从 1 开始,只增不改号 引用永远有效
全文公开 任何人免费下载 实现不必求人
只增不删 作废也留着,标 Historic 历史可追溯

第一行那个「只增不改号」是关键设计: 一份 RFC 一旦发布,编号就固定了,内容也不会被原地修改。 要改就发一份新的,然后在新文档里写「Obsoletes: 793」。 所以「RFC 793」永远指 1981 年那份 TCP 规范, 不会某天变成别的内容——这让所有引用都稳定可靠。 第三行是「可追溯」的来源:被废弃的 RFC 不删除,只标 Historic, 所以你能查到「当年为什么这么设计」。 这一点在工程上极有价值——很多「看起来奇怪的规定」,答案就在某份 Historic 文档里。

二、两份对照

同一份规范的头部,四十年前后差别很大:

字段 RFC 791(1981) RFC 9293(2022)
编号 RFC: 791 Request for Comments: 9293
状态 没有这一栏 Category: Standards Track
替代关系 没有 Obsoletes: 793, 879, ...
作者单位 prepared for DARPA W. Eddy, Ed. / MTI Systems
标准化号 无 STD: 7

第二、三行是新加的:1981 年那份没有「状态」也没有「替代关系」, 因为当年还没有「成熟度等级」这套制度。 这套制度是后来才建立的,所以老文档里查不到,只能靠外部索引判断。 第四行那个 STD: 7 是另一套编号:STD 系列是「已经是正式标准」的汇总编号, 一个 STD 号可能对应好几份 RFC。 所以「查 RFC 9293 是不是正式标准」的答案在 STD: 7 这一行。

三、怎么读一份 RFC

顺序很重要,能省掉大量时间:

| 顺序 | 看什么 | 能回答什么 | |---|---|---|---| | 1 | 头部 | 是不是现行版、有没有被替代 | | 2 | Status of This Memo | 能不能商用、是不是草案 | | 3 | 目录与 Abstract | 这份文档管不管你要问的事 | | 4 | 搜 MUST/SHOULD | 硬边界在哪 |

第一步最容易跳过,但最重要:很多网上流传的「RFC 编号」其实是废弃版, 照着它实现就会出错。 先看头部有没有 Obsoleted By,一步就能排除。 第四步是效率技巧:一份 RFC 几十页,但硬性要求往往只有十几条,全部标着 MUST。 先搜这三个词,再回头看上下文,比通读一遍快得多。 顺带说一句「Status of This Memo」那一段:它写的是「这份文档的使用许可」, 老 RFC 里有「不得部分引用」这类限制,新的一般是自由使用。 这段话经常被跳过,但它决定了你能不能把内容抄进产品文档。

四、动手 Demo:RFC 的开头是一套固定格式

真拉两份对照:一份 1981 年的老规范,一份 2022 年的新规范。 头部字段的差异,就是标准化制度演进留下的痕迹。

import urllib.request

def head(url, n):
    req = urllib.request.Request(url, headers={'User-Agent': 'demo'})
    with urllib.request.urlopen(req, timeout=8) as r:
        raw = r.read(n)
    if raw.startswith(b'\xef\xbb\xbf'):
        raw = raw[3:]
    return raw.decode('latin-1')

for tag, url, n in (('RFC 791', 'https://www.rfc-editor.org/rfc/rfc791.txt', 900),
                    ('RFC 9293', 'https://www.rfc-editor.org/rfc/rfc9293.txt', 2600)):
    print('==', tag)
    got = 0
    for l in head(url, n).split('\n'):
        if not l.strip():
            continue
        print(l.rstrip()[:78])
        got += 1
        if got >= 9:
            break

实跑输出:

--------------------------------------------------------------------
RFC 的开头是一套固定格式
--------------------------------------------------------------------
**标准文档不是散文,它有固定格式。**下面真拉两份对照:一份 1981 年的老规范,一份 2022 年的新规范。

**RFC 791(1981,IP)**

RFC:  791
                           INTERNET PROTOCOL
                         DARPA INTERNET PROGRAM
                         PROTOCOL SPECIFICATION
                             September 1981
                              prepared for
               Defense Advanced Research Projects Agency
                Information Processing Techniques Office
                         1400 Wilson Boulevard

**RFC 9293(2022,TCP)**

Internet Engineering Task Force (IETF)                      W. Eddy, Ed.
STD: 7                                                       MTI Systems
Request for Comments: 9293                                   August 2022
Obsoletes: 793, 879, 2873, 6093, 6429, 6528,
           6691
Updates: 1011, 1122, 5961
Category: Standards Track
ISSN: 2070-1721
                  Transmission Control Protocol (TCP)

**两份的头部长得完全不一样,这就是版本的痕迹**:
**1981 年那份只有 `RFC:` 编号和标题,没有状态、没有作者单位**;
**2022 年那份有工作组、编号、类别、ISSN、作者、日期一整套。**
**「Stream:」、「Category:」这些字段就是成熟度等级**,**它们决定了「这是正式标准,还是讨论稿」。**
**2.2.4 会讲这套等级怎么晋升。**

RFC 791 的头部只有 RFC: 791、标题、September 1981 和「prepared for DARPA」: 没有状态、没有替代关系、没有作者署名。 RFC 9293 的头部有六行元数据:STD: 7、Request for Comments: 9293、 Obsoletes: 793, 879, ...、Updates: 1011, 1122, 5961、Category: Standards Track、 ISSN: 2070-1721。这六行就是「这份文档在标准体系里的位置」。 注意 RFC 9293 文件开头有一个 BOM:那是 UTF-8 的字节顺序标记, 直接按 latin-1 解码会变成三个乱码字符,所以代码里先判断并去掉它。 读文本文件时遇到「开头三个怪字符」,多半就是这个原因。

30 秒实验

  1. 把 n 调大,找出 RFC 9293 里 Obsoletes 那一行的完整内容。
  2. 拉一份 RFC 768,看它的头部有没有 Category 这一栏。
  3. 搜一下你关心的话题对应的 RFC 编号,先看它有没有被 Obsoleted By。

常见误区

  1. 以为 RFC 就是「标准」。 RFC 里有大量讨论稿、实验稿、甚至笑话, 要看头部的 Category 才知道它是什么。
  2. 以为 RFC 会被「更新」成新内容。 编号固定、内容不改,要改就发新的并标 Obsoletes。
  3. 以为老 RFC 没价值。 被废弃的也留着,很多「为什么这么设计」的答案就在 Historic 文档里。
自测三问(点开对答案) 1. RFC 的「只增不改号」带来什么好处? —— **引用永远有效**:RFC 793 永远指 1981 年那份规范,不会某天变成别的内容。 要改就发新的并标 Obsoletes。 2. RFC 791 与 RFC 9293 的头部差在哪? —— **老的那份没有状态、没有替代关系、没有作者署名**; 新的有 Category、Obsoletes、Updates、STD 号等六行元数据。 3. 读一份 RFC 应该先看什么? —— **先看头部有没有被替代**,再看 Status of This Memo,然后看目录, 最后搜 MUST/SHOULD 找硬边界。

下一节讲 RFC 是怎么被「晋升」成标准的。

相关笔记