跳到主要内容

5.5 UDP 和 TCP 报文段报头格式

5.5.1 UDP 报头的格式

RFC-768)UDP 首部如下所示:

 0      7 8     15 16    23 24    31
+--------+--------+--------+--------+
| Source | Destination |
| Port | Port |
+--------+--------+--------+--------+
| | |
| Length | Checksum |
+--------+--------+--------+--------+
|
| data octets ...
+---------------- ...

其中:

  • 源端口(Source Port)、目的端口(Destination Port):各占 2 字节。
  • 长度(Length):即不包括伪首部、实际发送的 UDP 报文段长度,单位为字节。因此其最小长度为 8(即仅包含首部)。
  • 校验和(Checksum):对整个数据报(即伪首部+首部+数据)进行校验和。校验方式与 TCP 完全一致。

UDP 首部固定部分长度 8 字节。

5.5.2 TCP 报头格式

RFC-9293 3.1)TCP 报头格式如下所示:

 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 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Sequence Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Acknowledgment Number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data | |C|E|U|A|P|R|S|F| |
| Offset| Rsrvd |W|C|R|C|S|S|Y|I| Window |
| | |R|E|G|K|H|T|N|N| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Checksum | Urgent Pointer |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| [Options] |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| :
: Data :
: |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Note that one tick mark represents one bit position.

其中:

  • 源端口(Source Port)、目的端口(Destination Port):各占 16 位。

  • 序号(Sequence Number):占 4 字节,即 [0, 2321][0,\ 2^{32}-1],当序号增加到 23212^{32}-1 时下一个序号就回到 0,通常简称为 “seq”(小写)。当此报文为传输数据的报文时,序号表示当前报文中第一个字节位于整个数据的绝对位置。

    TCP 使用滑动窗口机制来管理需要接收哪些数据,因此不会出现当序列号回到 0 时无法区分是第 0 字节还是 第 2322^{32} 字节的问题。

    TCP 握手阶段 seq 出现 23212^{32}-1 是可能的,对方回复 ack 即回复 0,TCP 可以正确处理这一情况。

  • 确认号(Acknowledgment Number):占 4 字节,通常简称为 “ack”(小写)。数据接收方需要向数据发送方回复确认,此字段即用于向对方确认已收到的序号,表示的是期望收到对方下一个报文段的第一个数据字节的序号。即:

    若确认号为 N,则表示到序号为 N-1 为止的所有序号已正确收到。

  • 数据偏移(Data Offset):即此 TCP 报文首部的长度,占 8 位,单位为 4 字节。由于 TCP 首部固定部分长度为 5 个 4 字节,而此字段上限为 15,因此选项部分不能超过 40 字节。

  • 保留(Rsrvd):占 4 位,预留以后使用,现填充 0。

  • 控制位:接下来 8 个字段为标志,各占 1 位。

    • 拥塞窗口减少(CWR):用于通知接收方,发送方已减少其拥塞窗口,以减少接收方反复通知发送方遇到网络拥塞。
    • 显式拥塞通知(ECE):用于通知发送方,接收方已遇到网络拥塞。
    • 紧急(URG):表示此 TCP 报文中有紧急数据,需尽快发送。即当 URG 置 1 时,此报文不应按原来排队顺序发送,而需立即发送。(RFC-9293 3.8.5)注意:
      • 新的应用不应继续使用 TCP 的紧急机制,但 TCP 实现仍必须包括对紧急机制的支持。
      • TCP 实现必须为应用程序提供一种方法来获取还有多少紧急数据需要从连接中读取,或至少确定是否还有紧急数据需要读取。
    • 确认(ACK):表示此 TCP 报文用于确认。即当 ACK 置 1 时,确认号有效。注意,当出现 ACK(大写)时,表示的是此标志位,而出现 ack(小写)时,则表示确认号。
    • 推送(PSH):表示此 TCP 报文中的数据需尽快交付给应用程序。即当 PSH 置 1 时,此报文不应等待接收缓存填满后再交付给应用程序,应立即交付。
    • 复位(RST):表示此 TCP 连接出现严重差错,需要立即释放连接。
    • 同步(SYN):表示此 TCP 报文是用于建立连接时三次握手的报文。
    • 终止(FIN):表示此 TCP 报文是用于释放连接的四次挥手的报文。
  • 窗口(Window):指发送此 TCP 报文的一方接收窗口剩余空间的大小,占 2 字节,单位为 1 字节,通常记为 rwnd(小写)。用于告知对方自己的接收能力,即自己还能接收多少数据。

  • 校验和(Checksum):占 2 字节。TCP 校验和生成方法为“二进制反码求和”,具体的:

    1. 按照如下格式生成伪首部:

       0      7 8     15 16    23 24    31
      +--------+--------+--------+--------+
      | source address |
      +--------+--------+--------+--------+
      | destination address |
      +--------+--------+--------+--------+
      | zero |protocol| length |
      +--------+--------+--------+--------+

      其中:

      • 源地址(source address)、目的地址(destination address):支持 IPv4 和 IPv6 地址,若为 IPv4 地址则为 4 字节,若 IPv6 则为 16 字节。
      • 填充(zero):无意义,固定为 0。
      • 协议(protocol):IP 标头中的协议字段,参考 4.7 IP 数据报的结构及其每个域的意义
      • 报文长度(length):即不包括伪首部实际发送或接收的、单个报文长度,单位为 1 字节。因此单个报文段长度最长不能超过 21612^{16}-1 字节,即 65535 字节。然而实践中单个报文的大小通常取决于 MTU,即远小于 65535 字节。
    2. 在数据部分后面填充 0 直至数据部分长度为 4 字节的倍数

    3. 将校验和字段全部置为 0。

    4. 将处理后的整个数据报每 16 位(即 2 字节)分为一份,视作无符号整数按顺序相加,若产生进位则将进位部分抹去并加回。例如:

      • 第一份数据为 0xFFFF,第二份数据为 0x0002,将其视作无符号整数按顺序相加,得到结果 0x10001,产生了进位 1
      • 将进位抹去得到 0x0001,然后加回得到 0x0002,于是结果为 0x0002

      由于两个 16 位无符号整数相加最多只能产生 1 位进位,而相加结果 +1 后不可能再次产生进位,于是可视为只要相加结果超过 16 位,则截取结果的低 16 位并将结果 +1。

  • 紧急指针(Urgent Pointer):指明紧急数据的最后一个字节在当前报文段数据部分中的位置。因此单个报文段可以同时包含紧急数据和非紧急数据,而紧急数据放在非紧急数据前面。

  • 选项(Option):长度可变,最长为 40 字节。例如:

    • 最大报文段长度 MSS:在 TCP 选项部分中的 MSS 指发送此报文的一方愿意接收的最大报文段大小。
    • (RFC-2018)选择确认(Selective Acknowledgment):当分组乱序到达时,可选择对未按顺序到达的数据进行捎带确认

TCP 首部固定部分长度 20 字节。

相关词条:

  • 最大报文段长度 MSS(Maximum Segment Size)

    最大报文段长度本身含义指每个 TCP 报文段中数据部分的最大长度。需与 TCP 选项部分中的 MSS 做区分。

  • 接收方最大报文段 RMSS(Receiver Maximum Segment Size)

    指接收方愿意接收的最大报文段大小,单位 1 字节

  • 发送方最大报文段 SMSS(Sender Maximum Segment Size)

    指发送方发送的最大报文段大小,单位 1 字节,根据链路路径上最小 MTU、RMSS 等因素确定。

  • 报文最大生存时间 MSL(Maximum Segment Lifetime)

    指报文在网络上存在的最长时间。(RFC-768)标准 MSL 规定为 2 分钟。

  • 累计确认(Cumulative Acknowladgment)

    确认并非收到一个字节就确认一个字节,而是累计一定数量的数据再发送确认,例如:正确收到一整个报文段后对这个报文段中的数据进行累计确认。

  • 延迟确认(Delayed Acknowladgment)

    TCP 实现应当实现延迟确认,即正确收到一个报文段后可不立即发送确认,但不应过度延迟,延迟必须小于 0.5 秒,且每遇到以下情况之一应发送一个确认:

    • 每收到一个完整大小的报文段(即数据部分大小等于 RMSS 的报文段)。
    • 每累计收到 2×RMSS\bf{2 \times RMSS} 字节的数据。