TCP滑动窗口控制流量的原理

TCP提供一种面向连接的、可靠的字节流服务

(参考网站:

https://coolshell.cn/articles/11609.html

https://github.com/steveLauwh/TCP-IP/blob/master/TCP/TCP%20Sliding%20Window.md

https://wizardforcel.gitbooks.io/network-basic/7.html  非常好的   文章列表, 非常好的 图解

http://www.52im.net/thread-515-1-1.html     非常好的   文章列表, 非常好的 图解

 

一、可靠传输的要求
可靠的传输应该满足下面两个要求:
(1)传输的信道不产生差错;
(2)保证传输数据的正确性,无差错、不丢失、不重复、并且按序到达。
这里有两层意思,一是能够正确地传输数据,二是接收方能够及时处理发送方发送的数据。二、可靠传输的工作原理
TCP为了提供可靠传输:
(1)首先,采用三次握手来建立TCP连接,四次握手来释放TCP连接,从而保证建立的传输信道是可靠的。
(2)其次,TCP采用了超时重传来保证数据传输的正确性,使用滑动窗口协议来保证接方能够及时处理所接收到的数据,进行流量控制。
(3)最后,TCP使用慢开始、拥塞避免、快重传和快恢复来进行拥塞控制,避免网络拥塞。

1、超时重传 
发送一个报文段,会立即启动一个重传计时器,等待目的端口确认收到这个数据段。否则将超时重传。
2、确认响应 
对于一个收到的请求,将发送一个确认。这个确认通常要延迟几分之一秒。
3、首部校验 
TCP数据报文段中有收和数据的校验和。这是一个端到端的校验和。如果出错的话,则接收端不会发送确认,从而触发发送方的确认重传。
4、对收到的数据进行排序。 
由于IP数据报文在网络中经历的时间可能不一样,所以数据到达接收端可能会失序。而接收方的传输层会根据报文段中的序号,进行重新排序。
5、重复的而数据直接丢弃。
6、流量控制 
TCP可以通过窗口大小来进行流量控制,防止接收慢的主机缓冲区溢出。

滑动窗口机制即是发送方根据接收方返回的ACK:期望下次收到的序列号和WINDOW SIZE:希望接收的数据窗口大小来滑动传输窗口发送数据。

这就是滑动窗口的工作机制,当链路变好了或者变差了这个窗口还会发生变话,并不是第一次协商好了以后就永远不变了。
滑动窗口协议,是TCP使用的一种流量控制方法。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。
只有在接收窗口向前滑动时(与此同时也发送了确认),发送窗口才有可能向前滑动。
收发两端的窗口按照以上规律不断地向前滑动,因此这种协议又称为滑动窗口协议。
当发送窗口和接收窗口的大小都等于1时,就是停止等待协议。

 

来源: https://www.jianshu.com/p/688b6c5026bd

 

TCP协议、滑动窗口机制、TCP连接建立(三次握手)

Ø  两个主机进行通信实际上就是两个主机中的应用进程互相通信。

Ø  应用进程之间的通信又称为端到端的通信。

Ø  运输层的一个很重要的功能就是复用和分用。应用层不同进程的报文通过不同的端口向下交到运输层,再往下就共用网络层提供的服务。

Ø  “运输层提供应用进程间的逻辑通信”。“逻辑通信”的意思是:运输层之间的通信好像是沿水平方向传送数据。但事实上这两个运输层之间并没有一条水平方向的物理连接。

二、运输层的主要功能

Ø  运输层为应用进程之间提供端到端的逻辑通信(但网络层是为主机之间提供逻辑通信)。

Ø  运输层还要对收到的报文进行差错检测。

Ø  运输层需要有两种不同的运输协议,即面向连接的 TCP 和无连接的 UDP。

Ø TCP的特点:

=》 TCP 是面向连接的运输层协议。

=》每一条 TCP连接只能有两个端点(endpoint),每一条 TCP 连接只能是点对点的(一对一)。

=》TCP 提供可靠交付的服务。

=》TCP 提供全双工通信

=》面向字节流

注意:

==TCP 连接是一条虚连接而不是一条真正的物理连接。

==》TCP 对应用进程一次把多长的报文发送到TCP 的缓存中是不关心的。

==》TCP 根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节(UDP 发送的报文长度是应用进程给出的)。

==》TCP 可把太长的数据块划分短一些再传送。TCP 也可等待积累有足够多的字节后再构成报文段发送出去。

Ø  UDP 是面向报文的:

=》发送方 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交付下来的报文,既不合并,   也不拆分,而是保留这些报文的边界。

=》应用层交给 UDP多长的报文,UDP就照样发送,即一次发送一个报文。

=》接收方 UDP 对 IP 层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程,一次交付一个完整 的报文。

=》应用程序必须选择合适大小的报文。

三、 TCP的端口

Ø  端口用一个 16 位端口号进行标志。

Ø  端口号只具有本地意义,即端口号只是为了标志本计算机应用层中的各进程。在因特网中不同计算机的相同端口号是没有联系的。

四、TCP的连接

Ø  TCP 把连接作为最基本的抽象。

Ø  每一条 TCP 连接有两个端点。

Ø  TCP 连接的端点不是主机,不是主机的IP 地址,不是应用进程,也不是运输层的协议端口。TCP连接的端点叫做套接字(socket)插口

Ø  端口号拼接到(contatenated with) IP 地址后面即构成了套接字。

 套接字 socket = (IP地址: 端口号) 

每一条 TCP 连接唯一地被通信两端的两个端点(即两个套接字)所确定。即:

TCP 连接 ::= {socket1, socket2} = {(IP1: port1), (IP2: port2)}

五、可靠传输的工作原理

1、停止等待协议

                    

请注意:

1) 在发送完一个分组后,必须暂时保留已发送的分组的副本

2) 分组和确认分组都必须进行编号

3) 超时计时器的重传时间应当比数据在分组传输的平均往返时间一些。

可靠通信的实现:

Ø  使用上述的确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信。

Ø  这种可靠传输协议常称为自动重传请求ARQ(Automatic Repeat reQuest)。

Ø  ARQ 表明重传的请求是自动进行的。接收方不需要请求发送方重传某个出错的分组。

2、流水线传输

Ø  发送方可连续发送多个分组,不必每发完一个分组就停顿下来等待对方的确认。

Ø  由于信道上一直有数据不间断地传送,这种传输方式可获得很高的信道利用率。

六、TCP 的流量控制——滑动窗口机制

流量控制(flow control)就是让发送方的发送速率不要太快,既要让接收方来得及接收,也不要使网络发生拥塞。而TCP控制流量则是利用滑动窗口机制实现的。

     滑动窗口协议原理:对所有数据帧按顺序赋予编号,发送方在发送过程中始终保持着一个发送窗口,只有落在发送窗口内的帧才允许被发送;同时接收方也维持着一个接收窗口,只有落在接收窗口内的帧才允许接收。

开始的时候窗口比较小,然后开始增长直到有错误发生时为止;-窗口的滑动依赖于网络性能。通过调整发送方窗口和接收方窗口的大小可以实现流量控制,就象通过阀门控制水流速度一样。也就是说 TCP协议通过滑动窗口来实现流量控制差错控制以至于实现可靠传输。

     解释:TCP滑动窗口技术通过动态改变窗口大小来调节两台主机间数据传输。每个TCP/IP主机支持全双工数据传输,因此TCP有两个滑动窗口:一个用于接收数据,另一个用于发送数据。TCP使用肯定确认技术,其确认号指的是下一个所期待的字节

假定发送方设备以每一次三个数据包的方式发送数据,也就是说,窗口大小为3。发送方发送序列号为1、2、3的三个数据包,接收方设备成功接收数据包,用序列号4确认。发送方设备收到确认,继续以窗口大小3发送数据。当接收方设备要求降低或者增大网络流量时,可以对窗口大小进行减小或者增加,本例降低窗口大小为2,每一次发送两个数据包。当接收方设备要求窗口大小为0,表明接收方已经接收了全部数据,或者接收方应用程序没有时间读取数据,要求暂停发送。发送方接收到携带窗口号为0的确认,停止这一方向的数据传输。

滑动窗口机制为端到端设备间的数据传输提供了可靠的流量控制机制。然而,它只能在源端设备和目的端设备起作用,当网络中间设备(例如路由器等)发生拥塞时,滑动窗口机制将不起作用。

七、 TCP 的运输连接管理

1、运输连接的三个阶段

运输连接就有三个阶段,即:连接建立数据传送连接释放。运输连接的管理就是使运输连接      的建立和释放都能正常地进行。

连接建立过程中要解决以下三个问题:

Ø  要使每一方能够确知对方的存在

Ø  要允许双方协商一些参数(如最大报文段长度,最大窗口大小,服务质量等)。

Ø  能够分配运输实体资源(如缓存大小,连接表中的项目等)。

TCP连接的建立都是采用客户/服务器方式。

2.TCP 的连接建立—三次握手

三次握手传送的内容

第一次握手:建立连接时,客户端A向服务端B发送请求报文段,这时首部中的同步位SYN =1,同时选择一个初始序号seq= x.TCP规定SYN=1报文段不能携带数据,但是要消耗一个序号。这时,TCP客户进程进入SYN-SENT(同步已发送)状态,等待服务器确认。

第二次握手:服务器收到请求报文后,如同意连接,则向A发送确认,同时自己也发送一个确认报文段,确认报文段中SYN和ACK都置1,确认号ack = x+1,同时自己也为自己选择一个初始序号seq =y。注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时TCP服务器进程进入SYN-RCVD(同步收到)状态。
第三次握手:客户端A收到B的确认后,还要向B给出确认报文段。确认报文段的ACK=1,确认号ack =y+1,而自己的序号seq=x+1.此包发送完毕,客户端和服务器进入ESTABLISHED(TCP连接成功)状态,完成三次握手。
完成三次握手,客户端与服务器开始传送数据。为什么客户端A还要发送一次确认呢?主要是为了防止已失效的连接请求报文段突然又传送到了服务端B,因而产生错误。
3、三次握手建立 TCP 连接的状态

4、连接的释放

数据传输结束后,双方都可释放连接,但一方(设为A)释放连接前需获得另一方(设为B)的允许,如果此时B方仍有数据要传输,则连接不得释放,A仍要接收B的数据,直至B方数据传输完毕后,B方发出释放连接的要求,得到A方的许可确认后,B释放连接,A等待2SML后释放连接,此时通信结束。

如下图所示:

 

来源:https://blog.csdn.net/CSDN_Terence/article/details/77935297

--------------------

TCP-IP详解:滑动窗口(Sliding Window)

从传输数据来讲,TCP/UDP以及其他协议都可以完成数据的传输,从一端传输到另外一端,TCP比较出众的一点就是提供一个可靠的,流控的数据传输,所以实现起来要比其他协议复杂的多,先来看下这两个修饰词的意义:

1. Reliability ,提供TCP的可靠性,TCP的传输要保证数据能够准确到达目的地,如果不能,需要能检测出来并且重新发送数据。

2. Data Flow Control,提供TCP的流控特性,管理发送数据的速率,不要超过设备的承载能力

为了能够实现以上2点,TCP实现了很多细节的功能来保证数据传输,比如说 滑动窗口适应系统,超时重传机制,累计ACK等,这次先介绍一下滑动窗口的一些知识点。

滑动窗口引入

在阅读一些文章的时候看到一个大牛做的视频,非常不错易于理解滑动窗口的机制,可以先看下:http://v.youku.com/v_show/id_XNDg1NDUyMDUy.html

IP层协议属于不可靠的协议,IP层并不关系数据是否发送到了对端,TCP通过确认机制来保证数据传输的可靠性,在比较早的时候使用的是send--wait--send的模式,其实这种模式叫做stop-wait模式,发送数据方在发送数据之后会启动定时器,但是如果数据或者ACK丢失,那么定时器到期之后,收不到ACK就认为发送出现状况,要进行重传。这样就会降低了通信的效率,如下图所示,这种方式被称为 positive acknowledgment with retransmission (PAR)

1

滑动窗口

可以假设一下,来优化一下PAR效率低的缺点,比如我让发送的每一个包都有一个id,接收端必须对每一个包进行确认,这样设备A一次多发送几个片段,而不必等候ACK,同时接收端也要告知它能够收多少,这样发送端发起来也有个限制,当然还需要保证顺序性,不要乱序,对于乱序的状况,我们可以允许等待一定情况下的乱序,比如说先缓存提前到的数据,然后去等待需要的数据,如果一定时间没来就DROP掉,来保证顺序性!

在TCP/IP协议栈中,滑动窗口的引入可以解决此问题,先来看从概念上数据分为哪些类

1. Sent and Acknowledged:这些数据表示已经发送成功并已经被确认的数据,比如图中的前31个bytes,这些数据其实的位置是在窗口之外了,因为窗口内顺序最低的被确认之后,要移除窗口,实际上是窗口进行合拢,同时打开接收新的带发送的数据

2. Send But Not Yet Acknowledged:这部分数据称为发送但没有被确认,数据被发送出去,没有收到接收端的ACK,认为并没有完成发送,这个属于窗口内的数据。

3. Not Sent,Recipient Ready to Receive:这部分是尽快发送的数据,这部分数据已经被加载到缓存中,也就是窗口中了,等待发送,其实这个窗口是完全有接收方告知的,接收方告知还是能够接受这些包,所以发送方需要尽快的发送这些包

4. Not Sent,Recipient Not Ready to Receive: 这些数据属于未发送,同时接收端也不允许发送的,因为这些数据已经超出了发送端所接收的范围

对于接收端也是有一个接收窗口的,类似发送端,接收端的数据有3个分类,因为接收端并不需要等待ACK所以它没有类似的接收并确认了的分类,情况如下

1.  Received and ACK Not Send to Process:这部分数据属于接收了数据但是还没有被上层的应用程序接收,也是被缓存在窗口内

2.  Received  Not ACK: 已经接收并,但是还没有回复ACK,这些包可能输属于Delay ACK的范畴了

3.  Not Received:有空位,还没有被接收的数据。

发送窗口和可用窗口

对于发送方来讲,窗口内的包括两部分,就是发送窗口(已经发送了,但是没有收到ACK),可用窗口,接收端允许发送但是没有发送的那部分称为可用窗口。

1. Send Window : 20个bytes 这部分值是有接收方在三次握手的时候进行通告的,同时在接收过程中也不断的通告可以发送的窗口大小,来进行适应

2. Window Already Sent: 已经发送的数据,但是并没有收到ACK。

滑动窗口原理

TCP并不是每一个报文段都会回复ACK的,可能会对两个报文段发送一个ACK,也可能会对多个报文段发送1个ACK【累计ACK】,比如说发送方有1/2/3 3个报文段,先发送了2,3 两个报文段,但是接收方期望收到1报文段,这个时候2,3报文段就只能放在缓存中等待报文1的空洞被填上,如果报文1,一直不来,报文2/3也将被丢弃,如果报文1来了,那么会发送一个ACK对这3个报文进行一次确认。

举一个例子来说明一下滑动窗口的原理:

1. 假设32~45 这些数据,是上层Application发送给TCP的,TCP将其分成四个Segment来发往internet

2. seg1 32~34 seg3 35~36 seg3 37~41 seg4 42~45  这四个片段,依次发送出去,此时假设接收端之接收到了seg1 seg2 seg4

3. 此时接收端的行为是回复一个ACK包说明已经接收到了32~36的数据,并将seg4进行缓存(保证顺序,产生一个保存seg3 的hole)

4. 发送端收到ACK之后,就会将32~36的数据包从发送并没有确认切到发送已经确认,提出窗口,这个时候窗口向右移动

5. 假设接收端通告的Window Size仍然不变,此时窗口右移,产生一些新的空位,这些是接收端允许发送的范畴

6. 对于丢失的seg3,如果超过一定时间,TCP就会重新传送(重传机制),重传成功会seg3 seg4一块被确认,不成功,seg4也将被丢弃

就是不断重复着上述的过程,随着窗口不断滑动,将真个数据流发送到接收端,实际上接收端的Window Size通告也是会变化的,接收端根据这个值来确定何时及发送多少数据,从对数据流进行流控。原理图如下图所示:

滑动窗口动态调整

主要是根据接收端的接收情况,动态去调整Window Size,然后来控制发送端的数据流量

1. 客户端不断快速发送数据,服务器接收相对较慢,看下实验的结果

a. 包175,发送ACK携带WIN = 384,告知客户端,现在只能接收384个字节

b. 包176,客户端果真只发送了384个字节,Wireshark也比较智能,也宣告TCP Window Full

c. 包177,服务器回复一个ACK,并通告窗口为0,说明接收方已经收到所有数据,并保存到缓冲区,但是这个时候应用程序并没有接收这些数据,导致缓冲区没有更多的空间,故通告窗口为0, 这也就是所谓的零窗口,零窗口期间,发送方停止发送数据

d. 客户端察觉到窗口为0,则不再发送数据给接收方

e. 包178,接收方发送一个窗口通告,告知发送方已经有接收数据的能力了,可以发送数据包了

f.  包179,收到窗口通告之后,就发送缓冲区内的数据了.

2

总结一点,就是接收端可以根据自己的状况通告窗口大小,从而控制发送端的接收,进行流量控制

参考文章

1.http://www.cricode.com/2679.html

2.http://kb.cnblogs.com/page/209100/

 来源: https://blog.csdn.net/wdscq1234/article/details/52444277

 

TCP滑动窗口控制流量的原理

TCP的滑动窗口机制
TCP这个协议是网络中使用的比较广泛,他是一个面向连接的可靠的传输协议。既然是一个可靠的传输协议就需要对数据进行确认。TCP协议里窗口机制有2种:一种是固定的窗口大小;一种是滑动的窗口。这个窗口大小就是我们一次传输几个数据。对所有数据帧按顺序赋予编号,发送方在发送过程中始终保持着一个发送窗口,只有落在发送窗口内的帧才允许被发送;同时接收方也维持着一个接收窗口,只有落在接收窗口内的帧才允许接收。这样通过调整发送方窗口和接收方窗口的大小可以实现流量控制。

TCP滑动窗口技术通过动态改变窗口大小来调节两台主机间数据传输。每个TCP/IP主机支持全双工数据传输,因此TCP有两个滑动窗口:一个用于接收数据,另一个用于发送数据。TCP使用肯定确认技术,其确认号指的是下一个所期待的字节。 假定发送方设备以每一次三个数据包的方式发送数据,也就是说,窗口大小为3。发送方发送序列号为1、2、3的三个数据包,接收方设备成功接收数据包,用序列号4确认。发送方设备收到确认,继续以窗口大小3发送数据。当接收方设备要求降低或者增大网络流量时,可以对窗口大小进行减小或者增加,本例降低窗口大小为2,每一次发送两个数据包。当接收方设备要求窗口大小为0,表明接收方已经接收了全部数据,或者接收方应用程序没有时间读取数据,要求暂停发送。发送方接收到携带窗口号为0的确认,停止这一方向的数据传输。
我们可以看下面一张图来分析一下固定窗口大小有什么问题。



这里我们可以看到假设窗口的大小是1,也是就每次只能发送一个数据只有接受方对这个数据进行确认了以后才能发送第2个数据。我们可以看到发送方每发送一个数据接受方就要给发送方一个ACK对这个数据进行确认。只有接受到了这个确认数据以后发送方才能传输下个数据。 这样我们考虑一下如果说窗口过小,那么当传输比较大的数据的时候需要不停的对数据进行确认,这个时候就会造成很大的延迟。如果说窗口的大小定义的过大。我们假设发送方一次发送100个数据。但是接收方只能处理50个数据。这样每次都会只对这50个数据进行确认。发送方下一次还是发送100个数据,但是接受方还是只能处理50个数据。这样就避免了不必要的数据来拥塞我们的链路。所以我们就引入了滑动窗口机制,窗口的大小并不是固定的而是根据我们之间的链路的带宽的大小,这个时候链路是否拥护塞。接受方是否能处理这么多数据了。
我们看看滑动窗口是如何工作的。我们看下面几张图。


首先是第一次发送数据这个时候的窗口大小是根据链路带宽的大小来决定的。我们假设这个时候窗口的大小是3。这个时候接受方收到数据以后会对数据进行确认告诉发送方我下次希望手到的是数据是多少。这里我们看到接收方发送的ACK=3(这是发送方发送序列2的回答确认,下一次接收方期望接收到的是3序列信号)。这个时候发送方收到这个数据以后就知道我第一次发送的3个数据对方只收到了2个。就知道第3个数据对方没有收到。下次在发送的时候就从第3个数据开始发。这个时候窗口大小就变成了2 

 

这个时候发送方发送2个数据。


看到接收方发送的ACK是5就表示他下一次希望收到的数据是5,发送方就知道我刚才发送的2个数据对方收了这个时候开始发送第5个数据。
这就是滑动窗口的工作机制,当链路变好了或者变差了这个窗口还会发生变话,并不是第一次协商好了以后就永远不变了。
滑动窗口协议
滑动窗口协议,是TCP使用的一种流量控制方法。该协议允许发送方在停止并等待确认前可以连续发送多个分组。由于发送方不必每发一个分组就停下来等待确认,因此该协议可以加速数据的传输。
只有在接收窗口向前滑动时(与此同时也发送了确认),发送窗口才有可能向前滑动。
收发两端的窗口按照以上规律不断地向前滑动,因此这种协议又称为滑动窗口协议。
当发送窗口和接收窗口的大小都等于1时,就是停止等待协议。

来源: https://www.cnblogs.com/luoquan/p/4886345.html