408 · 计算机网络 · 第 5 章 · 分量 ★★★★

交给对方主机上的那个进程,而且不丢不乱

网络层只负责送到主机,传输层用端口送到进程。UDP 只做这件事;TCP 还要保证可靠,并且不把对方和网络压垮。

这一章只要会:

  1. UDP 与 TCP 的区别
  2. TCP 首部:序号、确认号、窗口
  3. 三次握手与四次挥手
  4. 拥塞控制的窗口变化
一 · 主线

从"送到主机"到"可靠地送到进程"

一台主机上有很多程序,数据给谁

端口
16 位的编号,标识主机上的一个进程。IP 地址 + 端口号 = 套接字

只要送到就行,不在乎丢不丢

UDP
在 IP 的基础上只加了端口和检验和。简单、快,但不可靠

必须一个字节都不能错 TCP

先约好
三次握手建立连接,四次挥手释放连接
不丢不乱
每个字节都编号,对方确认,超时就重传

发太快,对方来不及收

流量控制
接收方在每个报文段里告诉对方"我还能收多少"(接收窗口 rwnd)

发太快,网络堵了 拥塞控制

做法
发送方自己维护一个拥塞窗口 cwnd,没丢包就慢慢加大,丢包了就减小
二 · 重点

UDP 和 TCP 对比

UDPTCP
连接无连接面向连接
可靠性不可靠,尽最大努力交付可靠:不丢、不重复、按序到达
传输单位面向报文:应用层给多长就发多长面向字节流:把数据看成一串字节
首部8 B20 B 起
通信对象一对一、一对多、多对多只能一对一
流量控制、拥塞控制没有有
典型应用DNS、DHCP、实时音视频HTTP、FTP、电子邮件

UDP 首部只有 4 个字段

源端口2 B
目的端口2 B
长度2 B
检验和2 B

长度包括首部和数据。检验和要把首部和数据都算进去,计算时临时加上一个 12 B 的伪首部(含源 IP、目的 IP)。

端口

  • 熟知端口 0 ~ 1023,给服务器用
  • 客户端口由系统临时分配
  • 一条 TCP 连接由两端的套接字唯一确定:(源 IP, 源端口, 目的 IP, 目的端口)
三 · 重点

TCP 首部:序号、确认号、窗口

固定首部 20 B。大题读抓包数据时,就是按这个格式一个字段一个字段地对。

源端口16 位
目的端口16 位
序号 seq32 位
确认号 ack32 位
数据偏移4 位
保留
标志位ACK SYN FIN…
窗口16 位
检验和16 位
紧急指针16 位
字段含义
序号 seq本报文段数据部分第一个字节的编号
确认号 ack期望收到的下一个字节的编号。ack = n 表示 n − 1 及之前的都收到了
数据偏移TCP 首部长度,单位 4 B
窗口接收方告诉对方:我现在还能接收多少字节(rwnd)
SYN建立连接时置 1
FIN释放连接时置 1
ACK置 1 时确认号才有效。连接建立后所有报文段的 ACK 都是 1

2009 真题数据确认号是多少

甲向乙连续发送两个报文段,分别带 300 B 和 500 B 数据,第一个报文段的序号是 200。乙正确收到两个报文段后,发回的确认号是多少?

第一段:字节 200 ~ 499 第二段:字节 500 ~ 999 下一个期望收到的字节是 1000 → 确认号 1000
四 · 重点

三次握手和四次挥手

客户服务器SYN=1, seq=xSYN=1, ACK=1, seq=y, ack=x+1ACK=1, seq=x+1, ack=y+1FIN=1, seq=uACK=1, seq=v, ack=u+1FIN=1, ACK=1, seq=w, ack=u+1ACK=1, seq=u+1, ack=w+1数据传送连接建立半关闭:服务器还可以发数据再等 2MSL才关闭收到即关闭
蓝色是建立连接,红色是释放连接。x、y、u、v、w 都是各自当时的序号。

写序号的三条规则

  • ack 永远等于"对方上一个报文段的 seq + 它占用的序号数"
  • SYN 和 FIN 各占一个序号,即使不带数据
  • 不带数据的纯 ACK 报文段不占序号

所以第三次握手 seq = x + 1;如果它没带数据,客户发的第一个数据报文段 seq 还是 x + 1。

常被问到的"为什么"

  • 为什么握手要三次:防止已经失效的连接请求又传到服务器,让服务器白白建立连接
  • 为什么挥手要四次:服务器收到 FIN 后可能还有数据没发完,所以确认和自己的 FIN 分开发
  • 为什么最后要等 2MSL:保证最后一个 ACK 能到达;万一丢了,还来得及重发
五 · 重点

拥塞控制:会画 cwnd 的变化

481216202404812162024传输轮次(RTT)cwndssthresh = 16ssthresh = 12ssthresh = 8慢开始每轮翻倍拥塞避免每轮 +1超时cwnd 回到 13 个重复 ACKcwnd 减半
初始 ssthresh = 16。第 12 轮后超时,第 21 轮后收到 3 个重复 ACK。
阶段或事件条件cwnd 怎么变
慢开始cwnd < ssthresh每过一轮翻倍,但不能超过 ssthresh
拥塞避免cwnd ≥ ssthresh每过一轮加 1
超时认为网络严重拥塞ssthresh = cwnd ÷ 2,cwnd = 1,重新慢开始
收到 3 个重复 ACK认为只是个别报文段丢了立即重传(快重传);ssthresh = cwnd ÷ 2,cwnd = ssthresh,直接进入拥塞避免(快恢复)

实际能发多少,由两个窗口共同决定:发送窗口 = min(接收窗口 rwnd, 拥塞窗口 cwnd)。

2009 真题数据超时之后

MSS 为 1 KB,拥塞窗口为 16 KB 时发生超时。接下来 4 个 RTT 都传输成功,此时拥塞窗口多大?

ssthresh = 16 ÷ 2 = 8,cwnd = 1 每个 RTT 结束后 1 → 2 → 4 → 8 → 9 KB 到 8 时达到 ssthresh,之后每轮加 1

例:慢开始翻倍时被门限截住

ssthresh = 12,当前 cwnd = 8,下一轮是多少?

翻倍是 16,超过了 ssthresh 下一轮 cwnd = 12 再下一轮 = 13

上图第 16 轮到第 17 轮就是这种情况。

六 · 易错速记

选择题直接对表

确认号是"下一个想要的"不是"刚收到的最后一个"。收到 200 ~ 499,确认号是 500。
SYN、FIN 各占一个序号纯 ACK 不占。
TCP 首部 20 B,UDP 首部 8 BTCP 的数据偏移以 4 B 为单位。
超时回到 1,重复 ACK 减半两种情况 ssthresh 都变成当时 cwnd 的一半。
发送窗口取两者较小值题目同时给了接收窗口和拥塞窗口时,别只看 cwnd。
流量控制和拥塞控制不是一回事流量控制怕接收方来不及收,是两端之间的事;拥塞控制怕网络堵,是全局的事。
TCP 面向字节流,UDP 面向报文TCP 的序号按字节编,不是按报文段编。
MSS 只算数据部分不包括 TCP 首部。
七 · 看一眼就行

这些不用花时间

八 · 自测

先自己做,再点开看

客户发出 SYN 报文段,seq = 100。服务器回 SYN + ACK,seq = 300。写出第二、第三次握手的 seq 和 ack。
第二次:seq = 300,ack = 101 第三次:seq = 101,ack = 301
cwnd = 24 时收到 3 个重复 ACK。之后的 ssthresh 和 cwnd 各是多少?如果是超时呢?

3 个重复 ACK:ssthresh = 12,cwnd = 12,进入拥塞避免。
超时:ssthresh = 12,cwnd = 1,重新慢开始。

某时刻 cwnd = 4000 B,对方通告的接收窗口是 2000 B,发送方已发送但未被确认的数据有 1000 B。此时最多还能再发多少?
发送窗口 = min(2000, 4000) = 2000 B 还能发 2000 − 1000 = 1000 B
主机收到一个 TCP 报文段,seq = 500,带 200 B 数据,之前的数据都已收到。它发回的确认号是多少?

700。收到的是 500 ~ 699,下一个期望的是 700。