TCP可靠数据传输原理
传输的可靠概念
数据在传输过程中,不错位,不丢包,不乱序。
信道的不可靠特性
由于数据在传输过程中,可能存在丢包、可能存在路由缓存溢出等现象,导致数据出现丢包等不确定现象,这样就决定了可靠传输协议的复杂 性。
如何处理传输中的位错位
假设现在有一个信道,在传输过程中可能会产生位错误,那么接收方就需要做两件事:一是辨别数据是否正确,二是如何从错误中恢复过来。
首先解决第一个问题:
利用校验和检测位错误!
什么是校验和:https://blog.csdn.net/qq_34902437/article/details/87938913
第二个问题:
确认机制(ACK):接收方显式告知发送方分组已经正确接收
NAK:告诉发送方分组错误
发送方接收到NAK后,重传分组。
如何处理传输中丢包的问题
传输过程中如果ACK消息发生错误怎么办?
为ACK增加校验和
序列号:发送方给每个分组增加序列号
接收方丢弃重复分组。
接收方ACK消息中显示地加入被确认的分组的序列号。
如何处理传输中又可能丢包、又可能发生错误
校验和+序列号+ACK+重传并不能保证这两种情况的出现,这时需要引入超时重传机制。
发送方等待一个合理的时间:
如果没有收到ACK,重传
如果分组或者ACK只是延迟而不是丢失了
这样就会引起重复的问题,序列号机制可以处理
接收方需要在ACK中显式告知所确认的分组
需要增加定时器!
如何提高性能-----滑动窗口协议
由于上面的设计存在停等操作,相当于单线程。但是如果我们一次连续发出多个分组,此时性能就会倍数提高!
我们需要更大的序列号范围
还需要接收方、发送方需要更大的存储空间以及缓存分组。
窗口:发出去的,还没确认的消息(路上的消息)。
运行使用的序列号范围
窗口的尺寸为N :最多有N个等待确认的消息
滑动窗口:
随着协议的运行,窗口在序列号空间内向前滑动
GBN滑动窗口协议
ACK(n):确认到序列号n(包括n)的分组均已被正确的接收
可能收到重复的ACK
为空中的分组设置计时器
超时TimeOut(n)事件:重传序列号大于等于n,还未收到ACK的所有分组(此种发送方式存在潜在的资源浪费)
GBN的接受方,是没有缓存的,发送拥有最高序列号的、已被正确接收的分组的ACK,可能产生重复的ACK。
乱序到达的分组:
直接丢弃–》接收方没有缓存
重新确定序列号最大的、按序到达的分组
SR滑动窗口协议
Selective Repeat,由于GBK没有缓存机制,会丢弃掉乱序到达的数据,且发送方会重复发一些没有丢弃的包,从而影响效率,SR协议就来改进GBK。
优化:
接收方对每个分组单独进行确认
设置了缓存机制,缓存乱序到达的分组,不选择丢弃
发送方只重传那些没有收到ACK的分组
为每一个分组设置定时器
发送方窗口
N个连续的序列号
限制已发送且未确认的分组
接收方也有一个窗口!!!
TCP的可靠传输服务
由于ip层提供的服务是不可靠的,tcp通过重传机制来实现可靠传输服务,tcp使用流水线机制来提高性能,也就是滑动窗口机制,在滑动窗口机制下,如何进一步提高性能呢?这里就引出了累计确认以及单一计时器。
什么是累计确认呢?
在GBN里有提到过,发送方一旦接收到接收方返回的ACK码,就默认接收方已经接收到此ACK码之前的所有的数据,这里就要求接收方在返回ACK码的时候,有自己的严谨处理逻辑。具体实现细节是
单一计时器
由于tcp的计时器是单一的,那么如何确定这个合理的超时时间呢?超时时间过长,会导致性能下降(如果发生丢包,发现丢包的时间过长),过短的话,重传的概率会变高(网络波动引起数据晚到,而不是丢包,这种现象在超时时间过短的情况下也会重传)。
tcp设置超时时间采用了指数加权移动平均的方法。
预估超时时间 = (1-a ) * 预估超时时间 + a * 发出数据到接收到ACK的时间
用新的超时时间来原有的超时时间
超时时间 = 预估超时时间 + 安全边界
流量控制
如果发送方一直发,接收方处理不过来,会导致接收方缓存被打满,这样再传过来的数据会淹没接收方。
所以我们需要建立一个速度匹配机制来实现流量控制。
接收方每一次发送ACK给发送方时,会将自己缓存空间剩余大小告诉发送方,发送方接收到缓存剩余后,可以调整自己发送数据的速率。
假如接收方的缓存满了,发送方仍然可以发送很小的一个数据,这样是为了避免出现死锁(接收方要接收到数据才会返回ACK,发送方根据ACK中的缓存剩余来调整发送速率,如果缓存满了而不再发送数据,就会出现死等现象)
TCP的连接管理
三次握手
四次挥手
客户机和服务机都可以发起,一般是客户机发起
第一步:客户机给服务器发送FIN,说明客户机数据发完,准备关闭连接
第二步:服务器发送ACK,告诉客户机已收到准备关闭连接的请求
第三步:服务器发送FIN,表示已收到全部的数据
第四步:客户机确认收到服务器的FIN,并发送ACK,等待一段时间(为了避免此过程的ACK丢包)
关闭连接,服务器释放资源。
拥塞控制
拥塞主要发生在网络传输过程中,当数据太多太快的时候,路由器处理不过来(路由器缓存溢出、路由器缓存队列过长),就会出现拥塞。拥塞控制是为了维护整个网络环境不被挤爆,大家都做些牺牲来维护整个网络。
拥塞的代价
一:当多个主机同时竞争网络时,一旦产生拥塞,分组的延迟太大。
二:当考虑到超时重传时,拥塞会导致大量重传,重传又会导致拥塞,从而会影响网络的有效传输效率。
三:当考虑到多跳网络时,拥塞会导致上一跳的路由处理的努力也白白浪费。
如何进行拥塞控制
本质是控制网络的负载,管制发送方发送的速率。
端到端的拥塞控制
通过观察丢失、时延的频率来判断是否发生拥塞
网络辅助的拥塞控制
路由器向发送方反馈网络的拥塞信息,发送方从而调整发送速率。
TCP的拥塞控制机制
如何来控制发送速率?
通过设置一个rate来控制
如何感知网络拥塞?
超时事件的频率(timeout或者连续三个ACK–丢包)
如何合理调整发送速率?
加性增,乘性减
谨慎的增加发送速率,一直到发生拥塞情况。
一旦发生拥塞,就要快速减少发送速率,所以我们要将速率减半。
慢启动
初始的数值设为很小,很谨慎,远远小于带宽,所以我们需要快速增长发送速率,呈现出指数增长方式。但是指数性增长很快就会导致拥塞,所以我们需要设置一个值(拥塞避免阶段)来控制,当指数增长达到这个值的时候,我们需要将指数增长变为线性增长。
当第一次增长达到顶峰时候,就会将速率减为发生拥塞时速率的一般,继而采取线性增加的方式。
细节:收到三个ack时,说明当前网络还不是特别拥塞,还能发送数据,threshold切一半,采用线性传输,
当发生timeout时,说明当前网络拥塞很严重,threshold直接变为1,再采用慢启动方式,达到threshold时,再采取线性增加。
tcp性能分析
tcp的吞吐率
。
[外链图片转存中…(img-CjHTo4JD-1624805104490)]
当第一次增长达到顶峰时候,就会将速率减为发生拥塞时速率的一般,继而采取线性增加的方式。
细节:收到三个ack时,说明当前网络还不是特别拥塞,还能发送数据,threshold切一半,采用线性传输,
当发生timeout时,说明当前网络拥塞很严重,threshold直接变为1,再采用慢启动方式,达到threshold时,再采取线性增加。
tcp性能分析
tcp的吞吐率
平均吞吐率为0.75(拥塞窗口的大小/信道传输时间)