TCP协议
- 特点:有连接、一对一、提供可靠交付、全双工通信、面向字节流
- 首部:20B,源端口+目的端口+序号+确认号等
连接管理
- ACK:大写的ACK是一个标志位,用于表示是否接受到,除了三次握手的第一步,因为是发起者,所以并没有“接受”的过程。后续的所有TCP,ACK=1
- seq:用来标志自己当前的包编号,由发送者决定
- ack:小写的ack表示期待的下一个接受包,比如上一个你收到的包seq是114,那你期待的下一个包就是114+1 = 115
- SYN:用于建立连接的标志位,只出现在三次握手中的前两次报文。
三次握手
- 客户端发送 SYN 报文,
SYN=1, seq=x
- 服务器响应 SYN-ACK,
SYN=1, ACK=1, seq=y, ack=x+1
- 客户端确认 ACK 报文,
ACK=1, seq=x+1, ack=y+1
四次挥手
- 客户端发送 FIN 报文,
FIN=1, seq=x
- 服务器确认 ACK 报文,
ACK=1, seq=y, ack=x+1
- 服务器发送 FIN 报文,
FIN=1, seq=y
- 客户端确认 ACK 报文,
ACK=1, seq=x+1, ack=y+1
可靠传输机制
- 序号(Sequence Number):用于数据排序
- 确认号(Acknowledgment Number):确认已收到数据的下一个期望字节序号
- 超时重传:未收到ACK超时后重发
- 累积确认:可批量确认多个报文,每次确认x,代表x+1没收到,x之前的全收到了。
- 滑动窗口:与流量控制配合使用
RTT估计和重传定时器调整
- TCP会对每个数据包计算往返时间(RTT),用于动态调整重传超时(RTO)值,保证可靠传输同时避免不必要的重传。
- 估计RTT通常采用 指数加权移动平均(EWMA) 方法:
- 这里的 α 是平滑因子(通常取0.1到0.2之间)。
例如:
已知当前TCP连接的RTT值是35ms,连续收到3个确认报文段,它们比相应的数据报文段的发送时间滞后了27ms、30ms与21ms,设α = 0.2,计算第三个确认报文段到达后新的RTT估计值?
解答:
1)RTT=(1-0.2)* 35 + 0.2 * 27 = 33.4ms
2)RTT=(1-0.2)* 33.4 + 0.2 * 30 = 32.7ms
3)RTT=(1-0.2)* 32.7 + 0.2 * 21 = 30.4ms
所以当第三个确认报文到达后,新的RTT估计值是30.4.
流量控制
接收窗口(rwnd)
rwnd就是 receive window。
- 接收方维护一个接收缓冲区;
- 每接收到一些数据,并将其交给应用层处理后,就会更新
rwnd
- 发送方根据
rwnd
控制发送速率,不发送超过 rwnd 字节的未确认数据。
拥塞控制
概念解释:
- 拥塞窗口(cwnd):一个根据拥塞情况估计的窗口值,实际发送会和rwnd结合取小值。
- 慢启动阈值(ssthresh或Threshold):一个限制慢启动的阈值。
- 慢启动:不是指启动的慢,而是从慢开始启动,启动速度很快,翻倍指数成长
图中我们可以看到RTT在1-6的时候就是翻倍增长,此时就是慢启动,在后面cwnd=32的时候停下是因为到达了慢启动阈值ssthresh=32,进入拥塞避免状态。
- 拥塞避免:到达ssthresh之后,每个RTT使 cwnd + 1,慢慢增长
图中我们可以看到6-16区间就是我们的拥塞避免状态,此时的rwnd从32到了42。
这个状态将持续到出现多个(3个)重复ACK,代表某个数据包可能丢失,接收方一直确认上一个正确的数据段。
- 快重传:快重传会快速重传发送方不再等待超时,立即重传。
- 快恢复:在快重传之后会立即触发,ssthresh = cwnd / 2; cwnd = cwnd / 2。
上图可以看到cwnd 从原值42变为了21,并且此时ssthresh 也变为 21。
- 超时重传:一直没有接收到ACK,触发超时。将ssthresh = cwnd / 2; cwnd = 1 MSS;
图中可以看到在RTT=22时发生超市。
总结触发条件和效果:
- 慢启动:
- 触发条件:初始触发或超时重传触发;
- 效果:cwnd = min(cwnd * 2, ssthresh);
- 拥塞避免:
- 触发条件:cwnd达到ssthresh
- 效果:cwnd ++;
- 快重传快恢复:
- 触发条件:多次重复ACK
- 效果:ssthresh = cwnd / 2; cwnd = cwnd / 2;
- 超时重传:
- 触发条件:一直没收到ACK,超时。
- 效果:ssthresh = cwnd / 2; cwnd = 1 MSS;
UDP协议
- 特点:无连接、首都开销小、最大努力交付,应用层要保证可靠性
- 首部:8B,分别为源端口号、目的端口号、长度、校验和
- 校验:采用首部、伪首部、数据进行二进制反码运算求和再取反