TCP的可靠传输保证
1|0TCP是一个可靠传输协议,那么是如何保证传输的可靠性呢?
1|1可靠性保证技术
- 检验和
- 序列号和确认应答
- 超时重传
- 流量控制
- 拥塞控制
1|2校验和
校验和:在数据传输过程中,对传输的数据进行计算和验证,检测是否有错误或损坏,假如有差错就会直接丢弃TCP 段,重新发送。
TCP在计算检验和时,会在TCP首部加上一个12字节的伪首部。
检验和总共计算3 部分:
- TCP首部
- TCP数据
- TCP伪首部
1|3序列号和确认应答
序列号和确认应答:在每个数据包上加上序号和确认标志,保证数据包按序到达并得到接收方的回复
-
发送方:每次发送数据时,TCP就会给每一个数据包分配一个序列号并且在一个特定时间内等待接收端对这个序列号进行确认,如果没有在特定时间内接收到接受方的确认信息,则会重新发送此数据包
-
接收方:利用序列号,对接收的数据进行确认,以便检测对方数据是否有误(丢失,乱序)接收端一旦收到已经顺序化的数据,就将这些数据按正确的顺序重组成数据流并传递到高层进行处理
序列号可以保证数据可靠性,比如去除重复数据包,避免乱序数据包
1|4超时重传
超时重传(与序列号息息相关:在发送方设置一个定时器,如果在一定时间内没有收到接收方的确认应答,就重新发送数据包。
常见的超时重传机制:
- 超时重传
- 快速重传
- SACK
- D-SACK
TCP超时重传情况
- 数据包丢失 (接收端未接收到发送方的数据包,发送方超过特定时间重新发送
- 确认应答丢失(接收方接收到对于的数据包,发送方没有回复确认信息,超过特定时间,发送方重新发送
特定超时时间
首先先了解 RTT(往返时延)数据从网络一端传送到另一端所需的时间,也就是包的往返时间。
超时重传时间就是RTO
存在两种问题:
- RTO时间过长(网络的空隙时间增大,降低网络传输效率
- RTO时间过小(RTT时间未结束,就开始重传,产生不必要的传输,导致网络负荷增大
RTO的值应该是略大于RTT的这次才能使重传机制更高效(因为网络是波动的,所以RTO应该是一个动态变化值。
Linux计算RTO一般是采用两个方式:
- 需要TCP通过采用RTT的时间,然后进行加权平均,算出一个相对平滑的RTO值,这个值应该是动态变化的
- 除了采集RTT时间,还要采集RTT的波动范围,避免有一个较大的时间波动
每当遇到一次超时重传的时候,都会将下一次超时时间间隔设为先前值的两倍。两次超时,就说明网络环境差,不宜频繁反复发送
缺点:超时触发重传存在的问题是,超时周期可能相对较长。
1|5滑动窗口&流量控制
流量控制
TCP 提供一种机制可以让「发送方」根据「接收方」的实际接收能力控制发送的数据量,这就是所谓的流量控制,而这种控制一般是通过滑动窗口实现的
滑动窗口
滑动窗口的实现原理:发送方和接收方都维护一个窗口,分别称为发送窗口和接收窗口。发送方在任意时刻能够发送的数据量不能超过发送窗口的大小。接收方在接收到数据后,会将自己的接收窗口大小通过TCP报文中的窗口字段告诉发送方,从而控制发送方的发送速率。
滑动窗口与操作系统缓冲区的关系
窗口和缓存:应用层没有及时读取缓存,会导致接收窗口收缩,同时server通过TCP报文通知发送方也减少发送窗口大小;若缓存被占满,则窗口大小为0,即窗口关闭
收缩窗口导致的丢包:服务器突然发送缓冲收缩行为,突然降低每个TCP连接的缓冲大小,同时为及时通知到发送方,导致客户端为及时收缩发送窗口,发送了过量的数据,超过缓存可处理的大小,导致丢包。
例如:发送端发送180字节,接收端的应用进程只接受了80字节进行处理,那么还有100字节缓存再缓冲区内,那么接收窗口就变小了100 变为 n-100 ,一次类推 慢慢的接收窗口就会越来越小
1|6拥塞控制
为什么需要拥塞控制,在网络出现拥塞时,如果继续发送大量数据包,可能会导致数据包时延,丢失等,此时TCP进行重传,只会导致网络负担严重,于是会有更大的时延,更多的数据丢失。主要目的就是为了防止【发送方】将数据填充到整个网络
拥塞窗口 cwnd是发送方维护的一个状态变量,他会根据网络拥塞程度动态变化,网络出现拥堵,cwnd变小,网络不拥堵,cwnd变大。
如果发现超时重传,就认为网络拥塞。
拥塞控制的主要算法
慢启动
TCP刚建立只能一点一点的提高发送数据包2的零次方开始 呈指数增加 当遇到慢启动门限停止增长
(慢启动门限 ssthresh)状态变量,当 cwnd < ssthresh 时使用慢启动,当 cwnd >= ssthresh 会启动拥塞避免算法
拥塞避免算法
一般ssthresh的大小为65535字节
拥塞控制算法的规则:当接收到一个ACK时,cwnd会增加 1/cwnd,称线性增加。
举例:当ssthresh为8:当8个ACK应答确认到来时,每个确认增加1/8,8个ACK确认时 cwnd一共增加1,变为9,变成为线性增加。
当触发了重传机制时,也会进入 拥塞发生算法。
拥塞发生
重传机制主要有两种:超时重传,和快速重传
超时重传
当发生超时重传,则会使用拥塞发生算法
这是ssthresh和cwnd会发生变化,ssthresh会变为cwnd/2,cwnd会重置为1
快速重传
则 ssthresh 和 cwnd 变化, cwnd=cwnd/2 ssthresh=cwnd,然后进入快恢复算法
1|7快恢复
快恢复算法过程:
- 拥塞窗口 cwnd=cwnd+n(n 表示为n个ACK被确认)
- 重传丢失的数据包
- 如果再收重复的ACK,则cwnd+1;
- 如果收到新数据的 ACK 后,把 cwnd 设置为第一步中的 ssthresh 的值,原因是该 ACK 确认了新的数据,说明从 duplicated ACK 时的数据都已收到,该恢复过程已经结束,可以回到恢复之前的状态了,也即再次进入拥塞避免状态
__EOF__
本文链接:https://www.cnblogs.com/Spoonblog/p/17230604.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了