%% # 纲要 > 主干纲要、Hint/线索/路标 # Q&A #### 已明确 #### 待明确 > 当下仍存有的疑惑 **❓<font color="#c0504d"> 有什么问题?</font>** # Buffer ## 闪念 > sudden idea ## 候选资料 > Read it later %% # 分组 packet **分组(packet)** 通常泛指**计算机网络中的数据包**,即**分组交换技术**下的**数据单元**,是一个抽象词汇。 具体到网络模型的不同层有不同含义,所指代的 **协议数据单元 PDU** 各不相同。 > [!NOTE] "分组"也常被用于特指网络层的 "**数据报**"。 <br><br> # 协议数据单元 PDU **==协议数据单元==**(Protocal Data Unit,**PDU**),一个通用术语,描述计算机网络中**任一层次上传输的数据单位**。 各层的 PDU 如下: | 层级 | PDU / 信息分组 | 封装操作 | | ----- | ----------------------------------------------------- | ------------------------------------------------- | | 应用层 | **==消息或报文==**(Message) | | | 传输层 | TCP **==报文段==**(Segment)<br>UDP **==数据报==**(Datagram) | 添加 **TCP 或 UDP 头部** | | 网络层 | **==IP 数据报==**(Datagram) | 添加 **IP 头部** | | 数据链路层 | **==数据帧==**(Frame) | 添加 **帧头**、**起始帧分界符**、**MAC 头部**、 **帧尾 FCS 帧校验序列** | - 传输层在**两个应用程序之间**(以端口号为标识)传输以"**报文段**" 为单位的数据; - 网络层在**网络上的网络节点间**(以 IP 地址为标识)传输以"**数据报**"为单位的数据; - 数据链路层**在同一物理链路广播域的两设备间**(以 MAC 地址为标识)传输以"**帧**"为单位的数据; - 物理层在物理媒介上进行**光信号或电信号**的传输,以 bit 为单位。 ## 各层的数据封装 在每一层中的一个**分组**都可以划分为两部分[^1](P96): - **首部/头部**(header) ——**当前层协议所添加的信息** - **有效数据载荷**(payload field)——即**来自上一层的分组**(包括上一层中添加的头部,以及上一层的有效数据载荷) ![[_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元 PDU 总结.assets/IMG-协议数据单元 PDU 总结-4A0CA36CA9B6459120FA8DE8A97D9D18.png|580]] > [!NOTE] 各层封装过程 > > ![img|631](_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元%20PDU%20总结.assets/IMG-协议数据单元%20PDU%20总结-3188E0F274AB286ECD7125A392FB1C65.jpg) > > [!caution] MAC 头部由 OS 协议栈中 IP 模块负责添加 > > 如下图所示, "**报头&起始帧分界符** + **帧尾 FCS 帧校验序列**" 才是**网卡**中的 MAC 模块负责的部分[^1]。 > > ![[_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元 PDU 总结.assets/IMG-协议数据单元 PDU 总结-51512E583CCC63218136C5B1E71051E0.png|622]] > <br><br> ## 数据帧的完整格式 下图中**不包含 "帧头"、 "起始帧分界符"、"FCS 帧尾"**。 ![MAC 层报文|691](_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元%20PDU%20总结.assets/IMG-协议数据单元%20PDU%20总结-B74B589F33CCA3DB0C5E602B9AB62531.jpg) - MAC 头部:14 字节(6+6+2) - IP 头部:`[20, 60]` 字节; - TCP 头部:`[20, 60]` 字节; - UDP 头部:8 字节; <br><br><br> # 数据包拆分——TCP 分段与 IP分片 **数据分割**——将较大的数据块拆分成较小的块进行传输。 在**传输层**、**网络层**分别存在两个**独立的拆分机制**: | | 相关概念 | 拆分机制 | | --- | ----------------------------------------------------------- | ------ | | 传输层 | ==MSS==——**最大报文段长度**,由 TCP 协议**下建立 TCP 连接的双方**在**握手阶段**协商确认 | TCP 分段 | | 网络层 | ==MTU==——**最大传输单元**,由**链路层协议**规定(如**以太网协议**) | IP 分片 | - 当**应用层的报文**超过 MSS 限制时,在**传输层**的 **TCP 协议**下就会发生 "**==分段==**"(UDP 协议中不涉及拆分)。 - 当**网络层的 IP 数据报** 超过 MTU 大小时,在**网络层**,则会进行 IP **=="分片"==**。 > [!NOTE] "TCP 分段" 与 "IP 分片" 相互独立 > > - 一个**应用层报文**可能在传输层**被划分为多个 TCP 报文段**, > - **每一个 TCP 报文段或 UDP 数据报**在网络层可能会被进一步划分为==**多个 IP 数据报**==。 > > > [!important] 传输层通常**根据==底层链路的 MTU== 来==设置 MSS== 以限制单个 TCP 报文段的大小**,从而**避免触发 IP 分片**。 > > **标准以太网链路的 MTU 通常为 1500 字节**,超过这一大小的 IP 数据报都会在网络层被分片。 > 考虑到 **IP 头部**、 **TCP 头部**通常各为 20 字节,**故==以太网中 MSS 通常被设置为 1460 字节==**,如下图所示: > > ![image-20240104183840238|311](_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元%20PDU%20总结.assets/IMG-协议数据单元%20PDU%20总结-33F8E33D4C180F0400B4B299A3055C9D.png) > > 在某些特殊网络环境中(如 VPN 或 PPPoE),MTU 的值可能会更小,相应的 MSS 也会减小。 > [!caution] UDP 数据报不会在传输层进行分段! > > **UDP 数据报被视为一个整体**,不会在 "传输层" 被拆分,每个 UDP 数据报在传输层都是独立处理和传输的。 > 如果 UDP 数据报的大小**超过了网络层 MTU 的限制**,则**会在 "==网络层==" 中被进行 "==分片=="**。 > <br><br> ## MTU 与 MSS - **==MSS==**(Maximum Segment Size,**最大报文段长度**) - **==MTU==**(Maximum Transmission Unit,**最大传输单元**) > [!NOTE] MTU = IP 首部长度 + TCP 首部长度 + MSS 参见[^1](P77) ![[_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元 PDU 总结.assets/IMG-协议数据单元 PDU 总结-6C454BBA94141C1B9902EC8F91C739B3.png|576]] ### MSS 最大段长度 **MSS** 是 **TCP 可以接受的==最大有效载荷==** 的大小,不包括 TCP 头部和 IP 头部。 MSS **由建立 TCP 连接的双方**在握手时协商确认, 其值通常**根据==链路层的 MTU== 确定**,旨在**避免整个 TCP 报文段在传输过程中被进行 ==IP 分片==**,从而提高数据传输效率。 > [!info] 通常设置 `MSS <= MTU - 40`。 (40 字节是最小 TCP 头部 + IP 头部的大小) <br> ### MTU 最大传输单元 MTU 指示了 **一条网络链路上** 可传输的 "**==链路帧==的有效载荷(即整个 IP 数据报)**" 的**最大大小**, 其值**由数据链路层协议(如以太网协议、Wi-Fi 协议)规定**。 > [!info] 常见链路的 MTU 默认值 > > 不同链路介质类型的网络有不同的默认 MTU 值,其中**以太网的 MTU 值为 1,500 字节**。 > > ![image-20240104181547656|209](_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元%20PDU%20总结.assets/IMG-协议数据单元%20PDU%20总结-9BFFFBD5912A332239E07807C210F13C.png) > #### 端到端链路的 MTU **每段链路的 MTU 可能都不相同**,一条**端到端路径的 MTU**由这条路径上**MTU 最小的那段链路的 MTU 决定**。 > [!example] > > 如下图所示,在主机 A 到路由器 B 之间的链路上 MTU 为 1500 字节,而在路由器 B 到路由器 C,以及路由器 C 到服务器 A 的链路上 MTU 为 1400 字节,因此**数据包在后两个链路上传输时被进行了分片**。 > > ![image-20240104214118311|773](_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元%20PDU%20总结.assets/IMG-协议数据单元%20PDU%20总结-BEAF291FB614EB5750F554A2C440E3C7.png) > <br><br> ## TCP 分段(Segmentation) 当应用层报文超过 **==MSS==** 时,TCP 会将其分割成**更小的 "TCP 报文段"**(TCP Segments),以适应传输层和网络层的要求。 TCP 分段**会给每个段分配一个序列号**,以确保接收方**可以将段按正确的顺序重组为完整的消息流**。 分段的好处在于,**如果传输途中有一个 TCP 报文段丢失或损坏,只需重传该报文段**,而无需重新发送整个应用层报文。 ![[_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元 PDU 总结.assets/IMG-协议数据单元 PDU 总结-C32DD406586B49BBD4578404B5D01A50.png|562]] <br> ## IP 分片(Fragmentation) 当路由器收到的 IP 数据报**超过下一条链路的 MTU** 时,就会**对该 IP 数据报重新分片**,以确保数据包可以**在物理链路上传播**。 IP包被分片后,每个片段都会保留原始IP头,并在其中添加 **==分片偏移量==**、**==标识符==** 等字段,以便接收方**可重新组装完整的包**。 分片如下图所示[^1](P171): ![[_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元 PDU 总结.assets/IMG-协议数据单元 PDU 总结-249E0A17663343DB130C412B5B91F127.png|691]] > [!caution] IP 层没有重传机制,IP 分片是无状态的,如果一个分片丢失,则 **==整个 IP 报文的所有分片==** 需要重传。 > > 正因如此,通常设置 MSS 小于 MTU,从而**避免 TCP 报文段在 IP 层分片**。 > [!example] 分片示例 > > 以 MTU=1500 字节为例 > > ![image-20240104195610315](_attachment/02-开发笔记/07-计算机网络/总结/协议数据单元%20PDU%20总结.assets/IMG-协议数据单元%20PDU%20总结-416F2E8B51402BE79BB2217939D47DE9.png) > > - 第一片报文,**IP 报文头 20 字节**,则数据载荷可容纳 1480 字节(数据载荷长度须是 8 的倍数); > - 第二片报文,**IP 报文头 20 字节**,数据载荷为剩余的 520 字节 <br>(总数据载荷长度 2000 字节减去第一片中已封装的 1480 字节) > > <br><br> # ♾️参考资料 - [4.1 TCP 三次握手与四次挥手面试题 | 小林coding](https://xiaolincoding.com/network/3_tcp/tcp_interview.html#%E6%97%A2%E7%84%B6-ip-%E5%B1%82%E4%BC%9A%E5%88%86%E7%89%87-%E4%B8%BA%E4%BB%80%E4%B9%88-tcp-%E5%B1%82%E8%BF%98%E9%9C%80%E8%A6%81-mss-%E5%91%A2) - [IP 层分片 & TCP 层分段](https://zhuanlan.zhihu.com/p/372863051) # Footnotes [^1]: 《网络是怎样连接的》