TCP的八大机制:
1. 确认应答
(保障TCP稳定的核心机制)
缺点:太繁琐,在信息传递过程中占用太多带宽
可能带来的问题:
- 发送消息丢失
- ACK丢失
2. 超时重发
内核:自动消息去重,避免资源浪费
Linux默认超时时间:500ms
策略:
- 发送时不会以固定频率发送,每次重发的频率(超时时间间隔)呈指数增加,举例如下:
第一次超时重发的时间间隔:500ms
第二次超时重发的时间间隔:2 *500ms
第三次超时重发的时间间隔:4 *500ms
…… - 发送一定次数后,消息仍未得到应答,就会强制关闭,停止发送(对方可能下线)
3. 连接管理
三次握手:(三次通讯)
SYN / SYN+ACK / ACK
为了验证收发两端的收发能力
举例:
三次握手的收发两端的收发能力一览
- | 发送能力 | 接收能力 |
---|---|---|
客户端 | × √ √ | × × √ |
服务器端 | × × √ | × √ √ |
两次握手可以吗?
- 不行,不能完整的证明客户端的接收能力和服务器端的发送能力
四次握手可以吗?
- 可以,但是没必要
四次挥手:(四次通讯)
FIN / ACK / FIN / ACK
为了确保收发两端能够正常关闭
举例:
三次挥手可以吗?
- 可能可以,如果接收缓冲区中无待结束的任务,那么两次挥手就可以合并(捎带应答)
- 对应到程序:接收缓冲区无数据时,就可以直接关闭连接
4. 滑动窗口
无需等待确认应答而可以继续发送数据
举例:
滑动窗口大小指的是无需等待确认应答而可以继续发送数据的最大值. 上图的窗口大小就是4000个字节(四个段).
如果16位的滑动窗口为0,那么发送端不会发消息给接收端,发送端会定时发送一个探测包,用来检测接收缓冲区的大小,如果接收缓冲区有值了,那么消息就可以继续发送了!
异常情况:
- 数据包已抵达,ACK被丢了
- ACK = 6001的含义:告诉主机A:1-6000已经被完整接收,而不是5001-6000被接收
- ACK返回的值是当前B接收缓冲区的下一个值(最大连续值)
- 也就是ACK只要最后一个返回正常,那么就说是正常的
- 数据包直接丢了
当前面的数据被正常补齐后,返回的ACK是最大值,这种机制叫"快重传"
5. 流量控制
以 结果(接收缓冲区的大小)为导向进行数据的传递
如果16位的滑动窗口为0,那么发送端不会发消息给接收端
16位窗口大小不是滑动窗口的大小,滑动窗口大小是固定的,不需要来传
所以,指的是:接收缓冲区窗口的大小,这个是动态变化的
TCP会以固定频率发一个检测包,用来检测接收区的空间大小的
当接收缓冲区不为0时,那么消息就会恢复发送
6. 拥塞控制
根据当前时间的网络来动态调整收发的频率
过程:
刚开始初始发送一个包,如果可以正常接收就会以指数增加发送的数据包的数量,一直增加到流量控制的最大值之后,就会从指数增长变成线性增长,一直进行收发,直到出现大量数据包丢失的时候:
- 将发包值置1
- 将流量控制的最大值设置为当前丢包的值的的一半,即将临界值设置为最大发包值
继续进行发包,一直循环此过程,整个过程叫做"慢启动"
7. 延迟应答
流量控制的基础上优化发送频率
注意:
延迟应答的时间一定要小于超时重传的时间,不能超过MSL,如果超过就会触发超时重传,会以为消息丢失了
Linux的默认延迟应答时间为200ms
策略:
- 固定一个时间段,发送一个延迟应答(一定程度加速发送消息的速度)
- 接收一定次数的包之后,每隔N次,发送一个延迟应答
8. 捎带应答
是针对于延迟应答的性能优化
是用来提高消息传输的性能