TCP 可靠传输的实现

前言

之前了解了TCP首部不同字段的意义,今天来看它们的第一个功能,可靠传输。下面再看一波首部样子留点印象。
在这里插入图片描述

功能描述

可靠传输

  • 无差错、不丢失、不重复、按序到达

接下来看看为了实现这个TCP搞了哪些东西。

滑动窗口

我们看到TCP首部有个窗口字段,长度是两个字节。实际上它是作为接收方使用的,用来通知发送方调整自己的发送窗口。 诶?发送窗口是啥,接收窗口又是啥? 这个不太熟悉不要紧,我们知道 TCP连接时两端各自都会有一个自己的发送缓存和接收缓存,发送消息时直接将数据写入发送缓存,接收消息时直接从接收缓存读取数据。

发送窗口和接收窗口就是在发送缓存和接收缓存上构造出来的窗口,用指针划分窗口的范围 。下面图片能看出它们的关系。
在这里插入图片描述
可能直接看这个图还不清楚,一会讲完发送窗口和接收窗口再回来看就觉得清晰了。

工作原理

用一个例子来加深下对发送接收窗口的理解和它们之间交互的细节。

情景:A 向 B 发送消息,B 向 A 发送确认。

  • 假设 B 上一个确认号 为 31
  • 假设 B 的窗口为20字节

A收到上面两个信息开始在缓冲区重新构造自己的发送窗口。

  • 下一个发送的字节序号是 31(30及之前的字节B全收到了)
  • 发送窗口大小为 20

然后就构造出如下窗口
在这里插入图片描述
这个发送窗口表示:在没有收到 B 确认的情况下,A可以将 31到50的数据全部发送出去,但是在没收到确认前都必须保留,用来进行可能发生的超时传输。

另外我们看到发送窗口有后沿和前沿,后沿左边的数据全都是已经收到确认的,可以在发送缓存中清除。前沿右边的都是发送窗口外还不能发送的数据。

假设: 此时 A发送了 31 到41的数据还没收到确认
在这里插入图片描述
现在发送窗口可以由三个指针分割

  • p2-p1 :已经发送,等待确认
  • p3-p2 :允许发送,但是还没发送
  • p3-p1 : A 的发送窗口

这时候来看看 B 的接收窗口,大小为20字节。
假设: B收到了32 、33序号的数据,也就是说未按序收到31 ,此时接收窗口如下
在这里插入图片描述
这时候怎么办呢?
因为 31 序号的数据没有收到(也许丢失了,也许滞留在网络中某处),这时候 B 回复的报文 的 确认号只能为 31(也就是期待下一个为序号31的数据)。

假设: B 又收到了31序号的数据,并把31~33序号的数据交付给主机,这时候 B就可以删除这些数据,将接收窗口 右移3个序号,同时给 A 发送确认(确认号为 34,窗口大小为 20)。

A收到B的确认后,就将发送窗口右移三个序号,此时可用窗口增大了。
在这里插入图片描述
若 A 继续发送 42 到 53的数据给B,且没收到确认,则发送窗口的 p2 和 p3 指针重合,可用窗口大小为 0 ,必须先停止发送。

存在一种可能性,B已经发送了确认,但是确认还在路上,为了可靠传输,A只能当做B还没发送确认。一旦超时,A就会重传这些数据。
在这里插入图片描述

总结一下
发送缓存用来暂时存放

  • TCP 已发送但是未收到确认的数据
  • 应用程序传给 TCP未发送的数据

接收缓存用来暂时存放

  • 按序到达,但是还没被应用程序读取的数据
  • 未按序到达的数据

强调三个事情

  • 虽然A的发送窗口是根据 B的窗口值设置的,但是同一时刻,两者的窗口值可能并不一样大,比如B确认中要改窗口大小,A还没接收到这个确认。
  • TCP对未按序到达的数据一般是先保存下来,等缺少的数据收到后,再按序交付给上层的应用程序
  • TCP要求接收方有累积确认的功能,可以减少传输开销。但是规定确认推迟时间不能超过 0.5 秒。接收方也能在自己有数据要发送时将确认信息顺便带上。

超时重传时间的选择

上面提到 当发送方超过一定时间没有收到确认后,就会重新传递这个序号的数据。

问题
传输层下面是互联网环境,我们的数据报可能只是经过一个高速率的局域网,也可能经过多个低速率的网络,并且每个数据报经过的路由还不同。因此 超时重传的时间怎么设定可以保证传输效率呢?

TCP 有一种自适应算法,也就是根据每个 报文的 RTT 一直更新自己的超时重传时间 RTO。
在这里插入图片描述
这里系数推荐 1/8 。
在这里插入图片描述
在这里插入图片描述
这里系数推荐 1/4 。

问题又来了,虽然知道了重传时间,但是这个时候 怎么判定 当前确认报文段 是对先发送报文的确定,还是对后来重传报文的确认呢 ?这个对加权平均 RTTs 计算的影响也是挺大的。
在这里插入图片描述
因此有一个对 Karn算法的修正版

每当发生重传,就将 RTO 增大为原来的两倍,直到不再发生重传,再按公式计算 RTO。
因此,Karn算法能使传输层分开有效的和无效的往返时间样本,从而改进往返时间的估测, 使计算结果更加合理。

选择确认SACK

现在还有一个问题,要是我们收到的报文无差错,只是没按序怎么办? 比如一开始中收到 32 、33 序号的数据,31序号的没收到,这时候怎么办呢?

1、大多数实现还是重传所有的数据块。
2、有人提出使用选择确认(SACK) ,也就是准确地告诉发送方我们已经接收到了哪些数据,但是TCP报文首部没有这个选项,所以要实现的话需要自己加一个字段。
在这里插入图片描述
然后再将已收到的数据告诉发送方,让它不要重复发送。
但是好像这个体系不太成熟,溜了溜了。

参考书籍
《计算机网络》 谢希仁

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值