数据从不整块上路——它被切成小块,每块套上信封(头部),才成为能在网络上跑的数据包。头部写着"从哪来、到哪去、第几块、有没有坏";到了对端再按序号拼回原文。这就是"数据打包"的全部含义:切块 + 加头 = 打包,脱头 + 拼块 = 收包。
一、为什么非要打包?(想想整块发会怎样)
先把反例摆出来:假设把 3 MB 的文件当成一整坨塞进线路,会撞上三堵墙:
- 占线——一坨货独占线路,别人的包只能在后面排队。就像有人抱着电话线不撒手
- 出错代价大——线路只要坏一个字节,整坨从头再来,3 MB 白传
- 没法轮流——网页、视频、语音同时在线,谁也别想插队
切成小块之后,三个麻烦一次性解决:
- 轮流上桌:一大堆小包可以交错着走同一条线路,谁都别想霸占(收 1.4 逐跳接力:路由器本来就是一包一包接力传的)
- 局部重传:坏了哪一块补哪一块(收 3.3:TCP 的补发机制就靠这个前提才成立)
- 大小可控:小块才塞得进各种粗细的线路(见下面第四点的"体重上限")
二、包长什么样:头部 + 数据
一个包就两部分:头部(信封) + 数据(信纸)。
头部里装的是"搬运工必须知道的信息":
| 头里写着 | 干什么用 | 谁填的 |
|---|---|---|
| 源地址 / 目标地址 | 从哪来、送到哪 | 网际层(IP) |
| 源端口 / 目标端口 | 交给哪个程序 | 传输层(TCP/UDP) |
| 序号 | 这是第几块,用于重组 | 传输层 |
| 校验和 | 数据在路上有没有被改坏 | 传输层 / 接口层 |
关键:一层一个头,层层套娃(收 1.6 封装旧账):
[ 帧头 ][ IP 头 ][ TCP 头 ][ 数据 ]
←接口层→ ←网际层→ ←传输层→
- 1.6 讲的是"逐层加外套"这件事本身;本节讲清了外套上写了什么——每个头都是给特定一层看的说明书。
- 每层只看得懂自己贴的那张:交换机读帧头、路由器读 IP 头、电脑里的程序读 TCP 头。这就是 1.6 说的同层对话,落地在此。
寄一张明信片,邮编写错,写得再美也到不了。网络上同理:地址、序号、校验和这些"信封上的字"才是包能走完全程的保证。
三、包的一生:打包 → 上路 → 拆包
① 发送方打包(自上而下,穿衣服) 数据从应用层往下走,每下一层就套一个头。到网络接口层时已经裹好三层信封,可以上车了。
② 线路上传输(只看自己那层) 沿途的交换机、路由器不关心数据内容,只读自己管得着的那层头,决定从这个口转发出去。数据部分全程不动。
③ 接收方拆包(自下而上,脱衣服) 一层脱一个头,每脱一层就把头里的话读完,再把剩下的交给上一层。一直到应用层,拿到的是原始数据本身。
④ 重组 传输层按序号把小包拼回原来的顺序,交给程序——中间有的包绕了远路、晚到了,靠序号照样归位。
发的时候一层层穿衣服,收的时候一层层脱衣服,中间的转发设备只看它管得着的那一件。
四、包的"体重上限":MTU 与分包
包不能无限大,因为每种链路都有自己的单包体重上限:
- 以太网的常见上限是 1500 字节,这个数字叫 MTU(最大传输单元)
- 数据超过 MTU 怎么办?网际层负责把它切成分片(IP 分片),到对端再拼起来
- 划重点:分片是 IP 层(网际层)干的,不是 TCP 干的。TCP 只负责决定"每块切多大",真正动手切的是 IP
- 分片的代价有两条:
- 开销变大——每个分片都要再带一个 IP 头,等于多贴几次邮票
- 丢一片,整包报废——一片没到,对端就拼不出完整的包,只能整套重来(收 3.3:可靠是 TCP 补的,它会重传整个包)
- 所以发送方会尽量把每块切得刚好:既不超重,也不至于头比货还多
它是很多"网络玄学"的根源——VPN 一连上网页就打不开、某些网站能 ping 通却打不开、部分服务时好时坏。十有八九是"包太大、路太窄、又被禁止分片"。下面的 Demo18 你会亲手摸到这条线。
五、动手 Demo18:亲手摸到包的体重上限
-
打开命令行(Win+R → cmd)
-
先发一个刚好卡在 1500 的包(应该通):
ping -f -l 1472 www.baidu.com -f= 不许分片("这一趟不许切开")-l 1472= 让数据部分塞 1472 字节- 1472 + 28(IP 头 20 + ICMP 头 8)= 1500,正好等于以太网 MTU → 通
-
⚠️ 教材/教程常写
-l 1472,但等价写法也有人写-l 1473(加的多算一个)。记住"1472+28=1500"这个算式就够 -
再加 1 个字节,看它撞墙:
ping -f -l 1473 www.baidu.com - 应该报错:
Packet needs to be fragmented but DF set(需要分片,但设置了禁止分片的标志) -
这句报错翻译过来就是:"这包超重了,卡口过不去"
-
反过来,允许分片再发一次大包:
ping -l 3000 www.baidu.com - 这回能通,但注意
time=会明显变大——因为它被切成了两片,对端还要拼回来 -
对比一下 1472 那次的延迟,感受"分片是有代价的"
-
30 秒观察:
1472 通、1473 不通这条分界线,就是你这条线路上的 MTU 边界。换了网络(尤其是 VPN、PPPoE 宽带)这条线会往左移(1464、1452 之类),因为隧道和拨号协议自己也要占掉几个字节的信封。
- 数据为什么要切成小块发,而不是整块发?说出两个好处。
- 一个数据包的头部至少装着哪几类信息?
- 打包和拆包分别发生在哪一端、朝哪个方向?
- 数据超过 MTU 时,是 TCP 去分片还是 IP 去分片?丢了一片会怎样?
答案: ① 一是能轮流共用线路(不独占),二是坏哪块补哪块、不必重传整个文件;附带好处是大小可控,能适应不同粗细的线路。 ② 源/目标地址、源/目标端口、序号(用于重组)、校验和——本质就四件事:送到哪、给谁、第几块、坏没坏。 ③ 发送方自上而下逐层加头(打包);接收方自下而上逐层脱头(拆包)。 ④ 网际层(IP)动手分片、对端 IP 负责重组;丢一片整个包就拼不齐,由 TCP 重传整个包。
常见误区:
- ❌ "数据是一整块在网上跑的" → 网上跑的从来是切过、加过头的包。"下载一个文件"只是看起来像一个整体,底下是成千上万个包在跑
- ❌ "包 = 数据" → 包 = 头部 + 数据。头部往往比数据本身更关键(地址、序号、校验全靠它)
- ❌ "分片是 TCP 的活" → TCP 只管"每块切多大",分片和重组是 IP(网际层)的动作(3.2 的两段论:IP 管全程)
- ❌ "包越大效率越高" → 超 MTU 要分片、头更多、丢一片全废;太小则头比货还多。所以才要刚好卡住
- ❌ "交换机和路由器会看数据内容" → 它们只读自己那层的头,数据全程原封不动(同层对话)
六、下一步学什么
- ☑ 3.5 接收和传输数据的规则(使用TCP/IP进行通信) ✅ 已完成 —— 点此复习:包上那些"序号",到了那一节被拿去对账了
相关笔记
- 接收和传输数据的规则(使用TCP/IP进行通信) —— 下一节:包上那些"序号",被拿去对账了
- 为驱动应用程序而做准备的网络分层(传输层与应用层) —— 本节头部里一半的字(端口、序号)是它填的
- 负责传输数据的网络分层(网络接口层与网际层) —— 分片归网际层管,本节把这条分工压实了
- 通信过程中所使用的语言(网络架构) —— "封装 = 加外套"的最早出处,本节讲清了外套上写什么
- 用于构建网络的设备(网络设备) —— 交换机认门牌、路由器看地图,正是"只读自己那层头"的肉身
- TCP通信 —— 那辆
byte[] cart = new byte[1024]的小推车,为什么不能一次拉完?因为数据是分包到达的 - UDP通信 —— Java 里那个
DatagramPacket类名直译就是"数据报/数据包",本节讲的包就是它