TCP数据段做为IP数据报的数据部分来传输的,IP层提供尽最大努力服务,却不保证数据可靠传输。TCP想要提供可靠传输,须要采起必定的措施来让不可靠的传输信道提供可靠传输服务。好比:出现差错时,让发送方重传数据;接收方来不及处理数据时,让发送方下降传输速度。
html
TCP传输的数据通常分为两类:交互数据、成块数据。交互数据通常较小,好比发送1个字节的交互数据,加上TCP数据段首部以及IP数据报首部,至少须要41个字节。在广域网,数量众多的交互数据会增长拥塞出现的可能。而成块数据的报文段基本上都是满长度的。
根据不一样状况,两种数据流采用不一样的传输方式。
算法
在互联网早期,通讯链路并不可靠,所以在链路层传输数据时要采用可靠的传输协议,其中最简答的协议叫“中止等待协议”。在运输层并不使用中止等待协议,只是传输交互数据流传输时采用的nagle算法和该协议的原理很相似。
数组
“中止等待”是指每发送完一个分组就中止发送,等待对方确认,在收到对方确认后再发送下一个分组。发送方在必定时间没有收到确认,则会重传分组。
缓存
一、当接收方收到错误数据分组时,会直接丢弃分组。
二、若是数组分组在传输的过程当中丢失。
网络
在这两种状况下,接收方都不会发送任何信息。发送方在必定时间内没有收到确认,就认为分组丢失,而后重传该数据分组,这就叫超时重传。
中止等待ARQ协议就是经过这种确认和重传的机制,在不可靠的网络上实现可靠通讯。
ide
在传输交互数据流时,通常采用nagle算法。nagle算法要求在一个TCP链接上最多只能有一个未被确认的小分组,在该分组的确认到达以前不能发送其余分组。值得注意的是:并非在收到确认以后马上发送其余分组,TCP链接上容许不存在数据分组。具体的nagle算法发送分组的规则以下:
cdn
一、缓存中的数据长度达到最大报文长度时,则容许发送。
二、缓存中的数据长度达到发送窗口大小的一半时,则容许发送。
三、报文段首部FIN标志位置为1,则容许发送。
四、报文段首部设置了TCP_NODELAY选项,则容许发送;
五、发生了超时(通常为200ms),则当即发送。
htm
TCP在未收到确认时收集这些零散的数据,当确认到达的时候,能够以一个报文段发送出去。确认到达的越快,数据发送的也就越快。
nagle算法可以有效解决交互类的小数据过多的问题,下降网络拥塞出现的可能。可是因为不是将缓存中收到的数据马上发送出去,所以会产生必定的时延。另外,接收方通常会延迟确认,以便将确认报文与要送的数据相结合起来,通常延迟时间为200ms。
对于一些实时应用程序来讲,nagle算法带来的延迟是不可以接受的。TCP标准规定,必须实现nagle算法,但也必须提供一种能够关闭nagle算法的方法。上述nagle算法规则中第四条说的TCP_NODELAY选项就是nagle算法被关闭的标志。
blog
成块数据每每超过最大报文长度,要进行拆分以后再发送,交互数据碎片化的问题不会出现。成块数据是经过基于滑动窗口协议来的连续ARQ协议完成的。
资源
使用基于中止等待协议的nagle算法的缺点是信道利用率过低。以下图所示:
一、前沿向右移动,这种状况发生在数据发送并被确认时。
二、后沿向右移动,容许发送更多数据。这种状况发生在接收窗口增大或者网络拥塞状况缓解时。
三、后沿向左移动,这种状况发生在接收方但愿发送窗口缩小时,TCP标准强烈不建议出现这种状况。由于发送方在收到缩小窗口的通知时,可能已经发送了一些缩小部分的数据,容易形成错误。
窗口前沿没法向左移动,由于TCP会将窗口以外已经收到确认的数据清除出缓存。
TCP要求接收方有累计确认功能,接收方没必要马上对收到的数据进行确认,这样能够减小传输开销。另外,在发送确认时也能够捎带上接收方要发送的数据。TCP标准规定确认推迟的时间不能超过0.5秒,若是收到一个具备最大报文长度的报文段,则必须隔一个报文段就发送一个确认。
累积确认功能使得接收方只对按序到达的最后一个分组发送确认,表示这个分组以前的分组已经所有到达。接收方不可以准确的通知发送方已经发送到接收方的数据分组。
例如,上图中序号五、六、七、九、10分组到达接收方,接收方发送的确认序号是8,即接收方没有收到序号8的分组,但愿下次收到序号8的分组。而序号九、10分组虽然已经到达的事实,发送方并不知晓。
这会致使一个问题:一旦发生超时重传的状况,发送方是否须要再次发送已经到达的数据?若是不须要,又该如何获知具体哪些数据已经到达?
滑动窗口协议 与 自动重传请求技术结合造成连续ARQ协议。连续ARQ协议根据超时重发数据方式的不一样分为后退N帧ARQ协议和选择重发ARQ协议。
在发生超时重传时,后退N帧ARQ协议不考虑确认序号以后的分组是否已经发送到接收方,直接从确认序号开始重传以后的数据。
选择重传ARQ协议是指在接收方收到未按序排列的数据流时,通知发送方重传缺失的数据,而不是重传所有数据。TCP数据段首部中添加选择确认选项SACK能够实现该目的。
对于每个链接,TCP管理这4个不一样的定时器:
一、重传定时器:决定什么时候重传未被确认的数据分组。
二、坚持定时器:使窗口大小信息保持不断流动。
三、保活定时器:检测空闲链接的另外一端是否崩溃或重启。
四、2MSL定时器:测量一个链接处于TIME_WAIT状态的时间。
在超时重传的状况下,若是将超时重传的时间设置的过短,会出现不少没必要要的重传,增大网络负荷;若是设置的时间太长,则使网络的空闲时间增大,下降传输效率。TCP采用一种自适应的算法来动态计算超时重传的时间。
一个报文段发出的时间与收到确认的时间只差就是报文段的往返时间RTT。平滑的往返时间RTT_S是RTT的加权平均值。第一次测量时,RTT_S等于RTT的值,以后测量到新的RTT值时按如下公式计算:
新的RTT_S = (1 - α)×(旧的RTT_S)+ α ×(新的RTT样本)
TCP标准推荐α的值为0.125。
RTT误差的加权平均值RTT_D,与RTT_S和新的RTT样本之差有关。第一次测量时,RTT_D的值取RTT的一半,以后的测量中采用以下公式:
新的RTT_D = (1 - β)×(旧的RTT_D)+ β × |RTT_S - 新的RTT样本|
TCP标准推荐β的值为0.25。
超时计时器设置的超时重传时间RTO由以下公式求得:
RTO = RTT_S + 4 × RTT_D
在实际测量报文段往返时间RTT时会遇到一些问题,以下图所示:
经过TCP链接发送数据,若是发送方发送数据很慢,容易形成资源浪费;若是发送方发送数据过快,接收方来不及接收会形成数据丢失。流量控制就是指在接收方可以接收的范围内,合理而又快速的发送数据。
利用滑动窗口机制能够实现对发送方的流量控制。在TCP链接创建时,接收方会在确认报文段中给出本身接收窗口的大小。在每次发送确认报文时可以根据状况动态调整接收窗口的大小,并将告知发送方。以下图所示:
糊涂窗口综合症是指仅仅有少许数据经过链接进行交换,而不是满长度的报文段。这样会致使网络传输的效率很低。
若是接收缓存已经存满,此时接收方的应用程序每次只从接收缓存中读取少许数据,则接收方的接收窗口会一直保持在一个较低的值,致使发送方每次只能发送少许数据,会致使糊涂窗口综合症。
若是发送方应用程序每次向发送缓存中写入少许数据,TCP选择每次收到数据以后当即发送,也会致使糊涂窗口综合症。
避免糊涂窗口综合症能够从两端采起解决措施:
一、接收方不通告小窗口。一般的算法是接收方不通告一个比当前窗口大的窗口(能够为0),除非窗口能够增长一个报文段大小(也就是将要接收的MSS)或者能够增长接收方缓存空间 的一半,不论实际有多少。
二、 发送方在存在满长度的报文段或者接收方通告窗口大小一半报文时才发送。
最大报文段长度MSS是指每个TCP报文段中数据字段的最大长度。数据字段长度加上首部长度就等于TCP报文段的长度。
MSS是在创建TCP链接时通讯双方协商肯定的。第一次握手时,发送方能够在首部中增长MSS选项,若是没有MSS选项,则MSS默认为1460字节。第二次握手时,接收方也能够在选项中增长MSS选项,最终MSS的值取链接双方声明的MSS中最小值。
若是数据链路层使用以太网的话,最大传输单元MTU为1500字节,IP数据报首部最少为20字节,TCP数据段首部至少为20字节,那么MSS最大为1460字节。若是数据链路层使用互联网,那么MTU=576字节,MSS最大为536字节。
在网络层,若是传输的数据大于MTU,则会在发送端进行数据分片,而后再接收端的网络层进行组合。若是其中任何一个分片产生错误,都会致使整个TCP报文段重传。所以TCP会对数据进行分段,分段以后的数据往下交付不会超过MTU,能够避免网络层对数据进行分片。在传输层,UDP不像TCP那样进行数据分段,UDP会将应用程序交付下来的整个数据封成一个数据报,若是数据报大小超过MTU,则由网络层进行分片。
拥塞控制是指防止过多的数据注入网络中,这样可使网络中路由器或者链路不致过载。如今通讯线路的传输质量通常都很好,因传输出现差错丢弃分组的几率很小。所以,判断网络拥塞的依据就是出现了超时。
TCP进行拥塞控制经常使用的算法有四种:慢启动、拥塞避免、快重传、快恢复。
TCP为发送方维持一个拥塞窗口,记为cwnd。拥塞窗口是发送方使用的流量控制,接收方声明的接收窗口是接收方使用的流量控制。发送方的发送窗口大小等于这两个窗口中的最小值。
拥塞窗口的值跟SMSS有关,SMSS为发送的最大报文段长度。旧的规定是拥塞窗口的初始值为1至2个SMSS,RFC 5681规定拥塞窗口的初始值不超过2至4个SMSS。具体规定以下:
一、若SMSS>2190字节,则cwnd=2×SMSS字节,且不得超过2个报文段。
二、若2190≥SMSS>1095字节,则cwnd=3×SMSS字节,且不得超过3个报文段。
三、若SMSS≥1095字节,则cwnd=4×SMSS字节,且不得超过4个报文段。
慢启动算法规定:拥塞窗口初始化后,每收到一个对新报文的确认,拥塞窗口就加一个SMSS的大小。拥塞窗口以字节为单位,可是慢启动以SMSS大小为单位增长。按照慢启动算法,通过一轮传输,拥塞窗口就增大一倍,这是一种指数增加的关系。
慢启动算法除了维持拥塞窗口cwnd变量以外,还维持另外一个变量慢启动门限ssthresh。当cwnd以指数增加的形式增加到大于或等于ssthresh时,就再也不采用慢启动算法,而是采用拥塞避免算法来进行拥塞控制。
拥塞避免算法规定:每次收到一个确认时将cwnd增长1/cwnd个SMSS。即再也不是像慢启动算法那样通过一轮传输cwnd翻倍了,而是通过一轮传输增长一个SMSS。这是一种加性增加的关系。
当拥塞发生时(超时或收到重复确认),cwnd被设置为1个SMSS。ssthresh被设置为当前窗口大小的一半,但最少为 2个报文段。
例如:假设TCP的ssthresh的初始值为 8 SMSS。当拥塞窗口上升到 12 SMSS时网络发生了超时,TCP使用慢开始和拥塞避免。拥塞窗口大小以下图所示:
若是个别报文段在网络中丢失,网络并无发生拥塞,这种状况下发送方收不到确认报文,在超时以后会重传该报文。发送方误觉得网络发生拥塞,错误的启动慢开始算法,下降了传输效率。
采用快重传算法可让发送方尽早知道个别报文段的丢失。快重传算法要求接收方不要延时发送确认,即便收到失序的报文段也要马上发送对已收到报文的重复确认。以下图所示:
在快重传算法执行后,发送方知道只是丢失个别报文,而不是网络发生拥塞。以后并不会执行慢启动算法,而是执行快恢复算法:调整门限值ssthresh = cwnd/2,同时设置cwnd = ssthresh + 3 SMSS。这种设置门限值为当前拥塞窗口的通常,同时根据门限值调整拥塞窗口的形式称为乘法减少。
为何要设置拥塞窗口的值为门限值加3个报文段,而不是直接等于门限值?这是由于发送方收到三个确认报文,就认为有三个分组已经离开网络到达接收方的缓存,这三个确认报文再也不占用网络资源,能够适当增大拥塞窗口的大小。
TCP数据流传输方式分为:交互数据流、成块数据流。交互数据流采用nagle算法来控制流量,成块数据流经过基于滑动窗口协议的连续ARQ协议完成的。连续ARQ协议根据超时重传时是重传所有数据仍是选择性的重传而分为:后退N帧ARQ协议、选择重传ARQ协议。
超时重传的时间是动态肯定的,根据报文段往返时间通过改进后的Karn算法来计算的。
流量控制就是指在接收方可以接收的范围内,合理而又快速的发送数据。发送方与接收方都要采起措施来防止糊涂窗口综合症状况的发生。
最大报文段长度MSS是在创建链接时由双方协商肯定的,TCP数据报的MSS受限于网络层的最大传输单元MTU。TCP会将应用程序交付的数据进行分段,每一个报文段加上TCP报文段首部以及IP数据报首部不会超过MTU,这样网络层就不会对TCP数据段进行分片。UDP会将应用程序交付的数据打包成一个UDP数据报,分片任务由网络层来完成。
TCP进行拥塞控制经常使用的算法有四种:慢启动、拥塞避免、快重传、快恢复。这四种算法通常都不是孤立使用的,慢启动和拥塞避免之间会根据拥塞窗口是否达到ssthresh以及是否发生重传来切换;快重传算法以后紧跟着使用快恢复算法。
如需转载,烦请注明出处:www.cnblogs.com/lidengfeng/…