TCP协议:报文段格式、连接管理、可靠传输、流量控制与拥塞控制。
5.3 TCP协议
5.3.1 TCP报文段
TCP特点
- 面向连接:使用前需建立连接,使用后释放连接。
- 点对点:每条TCP连接只能有两个端点(一对一)。
- 可靠交付:无差错、不丢失、不重复,按序到达。
- 全双工通信:双方可随时发送数据,设有发送缓存和接收缓存。
- 面向字节流:将应用程序数据视为无结构的字节流,TCP根据窗口和拥塞程度决定报文段长度。
TCP首部格式(最小20字节)
| 字段 | 长度 | 说明 |
|---|---|---|
| 源端口 | 2B | 发送方端口 |
| 目的端口 | 2B | 接收方端口 |
| 序号 | 4B | 本报文段第一个数据字节的序号 |
| 确认号 | 4B | 期望收到下一个报文段的第一个字节序号,表示之前数据已收到 |
| 数据偏移 | 4位 | 首部长度,单位4B |
| 保留 | 6位 | 置0 |
| URG | 1位 | 紧急指针有效 |
| ACK | 1位 | 确认号有效(连接建立后全为1) |
| PSH | 1位 | 推送,尽快交付应用 |
| RST | 1位 | 复位,释放连接 |
| SYN | 1位 | 同步,连接请求/接受标志 |
| FIN | 1位 | 终止,释放连接 |
| 窗口 | 2B | 接收窗口大小(rwnd) |
| 校验和 | 2B | 覆盖首部和数据,计算含伪首部(协议=6) |
| 紧急指针 | 2B | URG=1时有效,指示紧急数据字节数 |
| 选项 | 可变 | 如MSS、窗口扩大、时间戳、SACK等 |
| 填充 | 可变 | 使首部为4B倍数 |
例题(2009年38题)
甲发送两个TCP段,分别含300B和500B,第一段序号200。乙正确接收后,确认号 = 200+300+500 = 1000。选D。
5.3.2 TCP连接管理
连接建立(三报文握手)
- 客户发送SYN=1,seq=x(初始序号),进入SYN-SENT。
- 服务器回复SYN=1,ACK=1,seq=y,ack=x+1,进入SYN-RCVD。
- 客户发送ACK=1,seq=x+1,ack=y+1,进入ESTABLISHED。服务器收到后也进入ESTABLISHED。
特点:服务器资源在第二次握手后分配,易受SYN洪泛攻击。采用三次握手可防止已失效的连接请求报文段再次建立连接。
连接释放(四报文握手)
- 主动方发送FIN=1,seq=u,进入FIN-WAIT-1。
- 被动方回复ACK=1,seq=v,ack=u+1,进入CLOSE-WAIT(半关闭状态)。
- 主动方收到后进入FIN-WAIT-2。
- 被动方发送FIN=1,ACK=1,seq=w,ack=u+1,进入LAST-ACK。
- 主动方回复ACK=1,seq=u+1,ack=w+1,进入TIME-WAIT,等待2MSL后关闭。
- 被动方收到后进入CLOSED。
2MSL作用:保证最后一个ACK到达对方;防止旧连接报文段出现在新连接中。
保活计时器:防止客户端故障导致服务器长时间等待。
例题(2011年39题)
甲发送SYN=1,seq=11220,乙同意连接应回复SYN=1,ACK=1,seq=y,ack=11221。选项C中seq=11221,ack=11221正确。选C。
例题(2021年38题)
客户先发FIN,收到服务器的FIN并发送ACK后,客户进入TIME_WAIT。选B。
5.3.3 TCP可靠传输
- 校验:与UDP类似,伪首部协议字段为6。
- 序号:每个字节编号,序号字段指示第一个字节序号。
- 确认:累计确认,确认号表示期望收到的下一个字节序号。
- 重传:
- 超时重传:RTO基于RTT动态计算(Karn算法修正)。
- RTTs = (1-α)×旧RTTs + α×新RTT样本 (α=1/8)
- RTTD = (1-β)×旧RTTD + β×|RTTs - 新RTT样本| (β=1/4)
- RTO = RTTs + 4×RTTD
- Karn算法:重传时不更新RTT,每次重传RTO加倍。
- 快速重传:收到3个冗余ACK后立即重传丢失报文段(无需等待超时)。
- 超时重传:RTO基于RTT动态计算(Karn算法修正)。
5.3.4 TCP流量控制
- 基于滑动窗口,发送窗口 = min(rwnd, cwnd)。
- rwnd(接收窗口)由接收方通告,反映接收缓存容量。
- 持续计时器:收到零窗口时启动,到期后发送探测报文。
5.3.5 TCP拥塞控制
基本概念
- cwnd(拥塞窗口):发送方根据网络状况动态调整。
- ssthresh(慢开始门限):切换慢开始与拥塞避免的阈值。
- 发送窗口 = min(rwnd, cwnd)(此处假设rwnd足够大)。
四种算法
- 慢开始:初始cwnd=1,每收到一个ACK,cwnd加1(每RTT翻倍),直至cwnd ≥ ssthresh。
- 拥塞避免:每经过一个RTT,cwnd加1(线性增长)。
- 快重传:收到3个冗余ACK时立即重传丢失报文段(不等待超时)。
- 快恢复:快重传后将ssthresh设为cwnd/2,cwnd设为ssthresh(而非1),然后进入拥塞避免。
拥塞判断与处理
- 超时:ssthresh = cwnd/2,cwnd=1,重新慢开始。
- 收到3个冗余ACK(快重传):ssthresh = cwnd/2,cwnd = ssthresh,进入拥塞避免(快恢复)。
例题(2015年39题)
甲初始ssthresh=32KB,乙接收缓存16KB(即rwnd=16KB),初始cwnd=1KB。慢开始:1→2→4→8→16(4个RTT后达到16KB)。但发送窗口受rwnd限制,故窗口为16KB。选C。
例题(2017年39题)
MSS=1KB,RTT=5ms,rwnd=64KB。从1KB增长到32KB需慢开始:1→2→4→8→16→32,共5个RTT,时间5×5=25ms。选A。
例题(2020年38题)
拥塞窗口从8KB到32KB,若使用拥塞避免(线性增长),需24KB增长,每RTT增加1KB,需24RTT=48ms。选D。
例题(2009年39题)
超时时cwnd=16KB,ssthresh=8KB,cwnd重置1。慢开始:1→2→4→8(第1个RTT后为8,达到ssthresh),之后拥塞避免:9→10→11→12(第4个RTT后为12KB)。但选项无12,可能题目答案按另一种理解:第4个RTT后已发送完的确认使窗口增加?常见答案为9KB?原题解析常为:超时后ssthresh=8,cwnd=1;RTT1:1→2;RTT2:2→4;RTT3:4→8;RTT4:8+1=9。选C。
例题(2014年38题)
超时时cwnd=8,ssthresh=4,cwnd重置1。慢开始:1→2→4(达到ssthresh),拥塞避免:5→6→7→8→9→10→11→12→13→14(10个RTT后为14KB)。但接收窗口为10KB,故发送窗口=min(14,10)=10KB。选A。
习题精选
(2021年39题) UDP数据报12B数据+8B首部,效率12/20=60%;TCP段12B数据+20B首部,效率12/32=37.5%。选D。
(2013年39题) 收到序号1913、有效载荷100B,表示收到1913~2012,确认号应为2013;而确认号为2046,说明对方期望2046,故甲立即发送序号=2046,确认号=2013?不,甲发送的序号应是对方期待的下一个序号?仔细分析:甲收到乙的段,乙的序号1913,确认号2046,表示乙已收到甲发送到2045的数据,并期待甲发2046。甲现在要回复,应将自己的序号设为2046(因为甲之前可能已发送到2045),确认号应为乙的下一个期望序号,即1913+100=2013。所以选B?选项B是2046,2013,正确。选B。
(2019年39题) 第三次握手ACK确认号 = 对方初始序号+1 = 2046+1=2047。选D。
(2020年39题) SYN序号1000,FIN序号5001。中间发送的字节数 = (5001-1000) - 1(SYN占1)+ 1(FIN占1)= 4001?实际上FIN消耗一个序号,但发送的数据字节数 = (5001-1000)-1 = 4000。选C。
(2021年38题) 客户先发FIN,收到服务器FIN并发送ACK后,进入TIME_WAIT。选B。
(2010年39题) cwnd=4000,发送两个1000B段后,收到第一个段确认,接收窗口2000。此时已发送未确认:第二个段1000B,加上刚确认的段释放空间?具体计算:发送窗口=min(rwnd, cwnd)=2000,已发送未确认=1000,还可发送2000-1000=1000。选A。
(2019年38题) 快速重传条件:收到3个冗余ACK。图中在t3时刻收到第三个重复ACK,所以此时重传。选C。
(2021年40题) 甲发送seq=501,200B,收到确认ack=501,rwnd=500。此时甲已发数据到700(501
700),未确认,窗口500,还可发送到700+500=1200,即序号7011200。但选项中只有C:701~1000符合。选C。
笔记结束