# 【NO.307】数据从应用层的应用进程到最后的网络包是怎么一步步封装的？TCP怎么拆分？IP怎么分片？

![img](https://pic1.zhimg.com/80/v2-82994ab8b40a148b258251469813c26c_720w.webp)

上图是一个整体的网络包的结构，可以看到网络包层层封装的结构

### 1.因此如果问一句，那数据从应用层的应用进程到最后的网络包是怎么一步步封装的呢？

答：比较概括性的回答是：（为便于讨论，假设是一个web服务）

首先应用层的应用进程将http请求报文下发到运输层

运输层的TCP协议栈给http请求报文添加TCP头部封装成TCP报文段，然后下发到网络层

网络层的IP协议栈给TCP报文段添加上IP头部封装成IP包，然后下发到数据链路层

数据链路层也有各种协议，假设是以太网协议，那么会给IP包加上帧头和帧尾，形成帧，然后下发到物理层

物理层则将帧视为字节流，完全转化为相应的物理信号(电信号或光信号等)，在线缆、光纤等媒介中传播

### 2.进一步提问：那运输层收到应用层下发的数据后，TCP协议是怎么看待以及怎么打包封装的？什么时候会拆分？

1、TCP视应用层下发的http请求报文为字节流，TCP协议会根据规定的MSS（最大报文长度：规定了TCP报文所能携带的数据载荷的大小）判断是否进行拆分

2、如果字节流长度大于MSS，则需要进行拆分，拆分成合理的几块，然后为每一块添加上合适的TCP头部

3、TCP头部中的序号字段就是为此服务的，最终形成一个个TCP报文段，接收方对应的运输层收到这些TCP报文段后可以根据TCP头部信息进行组装还原原来的http请求报文

![img](https://pic2.zhimg.com/80/v2-d032d1c079979626fdc6d5f6c67f29f5_720w.webp)

### 3.再进一步提问：那网络层收到运输层下发的TCP报文段后，IP协议是怎么看待以及怎么打包封装的？什么时候会拆分？

1、IP协议会根据输出端口（其实也就是被链路层的各种协议类型所规定）的MTU（最大传输单元：它规定了IP网络包的最大长度包括首部和数据载荷）进行判断是否进行分片；例如以太网的MTU=1500字节

2、若TCP报文段小于MTU 减 IP头部长度，则IP不需要对TCP报文段分片

3、若TCP报文段大于MTU 减 IP头部长度，则IP需要对TCP报文段分片

分片是IP对整个TCP报文段一视同仁，也就是不会区分是TCP头部还是数据载荷，如下图所示

IP头部字段中的标识、标志、片偏移字段就是为此服务的

接收端的网络层收到这些分片过的IP数据报，会根据IP头部中的字段信息，对分片进行组装，还原TCP报文段后交给上层也即运输层

![img](https://pic3.zhimg.com/80/v2-ff5c9d06d1e634fa0b530375422dce22_720w.webp)

注意：

- IP分片是在TCP拆分后又进行了一次拆分；在接收端刚好相反，先IP组装分片，然后交给运输层TCP，之后再组装TCP数据报文段，最后交给应用层的应用进程
- TCP拆分：依据是MSS（最大报文段长度）
- IP分片：依据是各种转发端口的MTU（最大传输单元）

### 4.**补充**

![img](https://pic2.zhimg.com/80/v2-ae01c72d5a3acaba7ffb1cbfd4a5e419_720w.webp)

以太网帧的最大数据帧长度为1518字节

帧头包含目标MAC地址(6个字节)、源MAC地址(6个字节)、上层协议类型(2个字节)共14字节

帧的尾部是FCS校验位(4个字节)

故以太网帧的MTU = 1518 - 14 - 4 = 1500 字节

又因为IP头部最小为20字节，TCP头部最小为20字节，以及在实际的应用中，通常TCP会加一个12字节的时间戳，这些共计52字节

所以单个TCP每次能打包的最大数据量为MTU - 52 = 1448字节

原文地址：https://zhuanlan.zhihu.com/p/532302700

作者：linux