《计算机网络》知识总结-8.TCP中什么是滑动窗口技术?为什么要这个?

http://www.voidcn.com/article/p-zhgaofqd-bqd.html

前提

在讨论这个问题前,先提出一个问题,假定我现在要A要发送一些数据给B,A要怎么才能保证发送的量B在网络良好的情况下能承受得住呢?

答案:A在发送前B要告诉他自己的容量是多少,比如,我给你盛饭,你要先告诉我,你能吃多少饭,我保证不超过你的饭量,这样就不会浪费了。而你的饭量就是一个窗口,如果你的饭量会随着时间消化而变化,那么这个就叫会滑动的窗口

具体我们来说说怎么实现。

TCP中的滑动窗口是这样的。

A先发送一个数据包给 B,由于是第一次,每个人第一次都很容易放错,所以TCP也是纵容A犯错,所以第一次A爱发多少发多少。

B如果能接受那当好,B接收到后交给应用层程序处理,并响应给A一个确认包,同时告诉他,下一次发送的时候不能超过多少(告诉A,下一次B的接收窗口的大小)。

万一A发送的B不能接收呢?

这里要分2种情况:

  • 第一种情况,A在不知道窗口大小的前提发送了2个数据包,第一个能被接受,发送第二个时候,B接收的窗口满了,因而第二个包被丢弃。但是B收到了第一个包,所以会响应一个确认号ACK给A,A发送第三次的时候就知道发送多大了(A第三次就能保证发送多大才不会被B嫌弃了)。
  • 第二种情况,A发送第一个数据,B就已经接受不了了,导致B收到第一个包后就丢弃这个,然后B保持沉默,直到A超时(有些学过流量控制的人会说,不是有持久计时器persistence timer吗?问题是持久计时器不是这个时候用的,持久计时器是在B响应一个确认号中窗口为0时才开始计时的,我们这里,连确认号都没有,所以也就不存在这个计时器了,重发计时器到是有一个),然后超时计时器报了超时重发,A又重新发一个(TCP这里没有算法做这个大小调整),B不能接受,然后就进入死循环了。

面对第二种情况怎么办呢?

没怎么办,因为第二种情况根本不存在,由于TCP的协议规定了初始化最小窗口大小大于路由器的MTU,所以凡是大于MTU的都会被路由分片发送,所以B收到的字节大小都会小于窗口的初始值,简单的说,第一次都是百发百中的!!!不用担心哦,比起这还是担心一下怎么摆脱单身狗的队列吧。

之后,A每次只发送B能接受的数据包,而B会实时的响应给对方A还能发送的数据包。


上面我一直讲的什么是窗口,以及窗口的第一次交互遇到的问题。 
下面我们来研究一下

什么是窗口的滑动了呢?

我们先看,在网络良好的情况下,假设

B的接收窗口大小是500Byte,TCP中接收端只有接收并处理完数据后才能响应确认。

A发送0-300。 
B接收0-300处理后,告诉A,还有500(ACK=301)。 
A再发送301-400。 
B接收301-400处理后,告诉A还有 500(ACK=401)。 
A再发401-500。 
A再发501-700。 
B接收401-500处理后,高速A还有500(ACK=501)。 
A在发送501-1000。 
B接收到501-1000,再接收501-700窗口不够(或者说已经收到了),把比较迟接收的501-700丢弃,处理后告诉A还有500(ACK=1001)。

你会发现窗口一直都是500,那么问题来了是吧。但是你应该注意到了ACK!ACK是下一次期望收到的起始Byte位置,也就是说窗口是由2个属性构成的:起始Byte的位置+大小,而不是说只有大小,所以一开始为了让你好理解,所以骗你说窗口只有大小(把窗口比喻成饭量也是不合理的,因为没有考虑起始Byte的位置)。

那么大小为500Byte的窗口,起始位置在传输过程中不停的改变,就好像一辆火车在不停的滑动一样。所以我们就将他成为“窗口滑动技术

为什么要这个

该技术主要用来控制流量,防止数据的生产者(发送端A)的生产速度比数据消费者(接收端)的消化速度慢引起的生产过剩造成频繁的数据重发(这种重发不是超时重发,超时重发是指超过指定时间RTT还没收到响应。)。

同时在接收端的接收滑窗的大小不是固定的,虽然上面我们固定500byte,其实接收的滑窗可以在每一次响应确认号的时候改变自己的大小并告诉A发送端。

这一篇博文单方面地在网络良好的情况下分析窗口的两个属性,介绍窗口滑动技术和目的。而没有介绍具体是怎么实现。

下一章中将介绍滑窗的在恶劣的环境中怎么实现发送和接收,整个过程涉及发送滑动窗口和接收滑动窗口。

洗刷睡觉!zzz

《计算机网络》知识总结-9.滑窗技术实现的要点

回顾上一章节的内容

1。滑窗是传输层通讯两端用于协调彼此收发能力的技术,免得你顾着说,我都来不及听。 
2。TCP有3个字段(序号seq,确认号ack,窗口)用于实现滑窗技术。

现在我们来讲讲恶劣环境中滑窗的技术实现要点。

1。滑动窗口的建立:在连接建立后双发都知道对方的确认号ack(确认号ack是由seq产生的,接收方在接收到seq后,消耗的字节数+seq = ack,然后把确认号返回给发送方就可以了)。根据接收方的确认号和接收窗口大小,发送方就可以知道自己的发送窗口大小了。比如窗口大小为20,确认号为31,(ps:发送缓存中每个字节都会在连接建立后被编码,保存在传输控制块TCB中)那么缓存中可以发送的字节序号范围为:【31~50】。接收方的窗口也是31~50。

这里我要说一下,上面的概念我是直接从教科书上搬过来的,其实课本有存在过度描述的嫌疑,如果按照课本的理解,客户端有发送和接收窗口,服务端也有发送和接收窗口,那岂不是一个TCP链接就有4个窗口了。

而事实上经过理解,发送窗口其实就是接收窗口,只是站在发送端,被认为是发送窗口,站在接收端被认为是接收窗口。为了统一概念,我们认为从发送端到接收端,方向只有一个窗口那就是接收窗口(发送窗口,是接收窗口的映射,所以我们认为他不存在了)。

结论:一个TCP链接有2个接收窗口,分别位于客户端和服务端。

2。在接收端的角度,窗口的头永远是未确认的,如果接收程序处理了确认号为开头的连续字节窗口才会滑动,否则永远不滑动窗口。(站在发送端的角度可理解为,发送端在发送分组数据后接收到返回的确认前不会移动窗口)。窗口不可以滑动,但是可以根据需要扩大。

3。接收窗口中的数据为: 
- 按顺序到达,却未被处理的。 
- 没按顺序到达的数据。 
这两类数据为未确认数据,如果接收端在一定时间内未收到确认(RTT超时了),就会重发。

4。接收端只要窗口头部存在已处理的连续的(有顺序)的字节,就会向发送返回确认ACK,然后滑动窗口。

5。发送端只需要一股脑的发送分组数据,只要发送的字节数不超过接收窗口的大小就行。

整个滑窗的技术要点就这些了,其实教科书讲的很复杂,因为原本只有一个东西“接收端的滑动窗口”,硬要分成2个来讲。

所以,我们只要理解接收窗口的特点就行了(2。3。4。为重点)。

本站公众号
   欢迎关注本站公众号,获取更多程序园信息
开发小院