上一篇http://www.cnblogs.com/whc-uestc/p/4715334.html中已经讲到TCP跟踪一个拥塞窗口来(cwnd)提供拥塞控制服务,通过调节cwnd值以控制发送速率。那么TCP如何基于丢包事件来设置cwnd值?通过TCP拥塞控制算法来实现。TCP拥塞控制算法主要有三部分:慢启动、拥塞避免、快速恢复。

1、慢启动

  当一条TCP连接开始时,cwnd的值一般初始设置为MSS的较小值。因为只有当发送方接收到ACK,才会更新cwnd的值,所以在一个RTT时间内,发送方只能发送cwnd字节大小的数据,这就使得初始发送速率大约为MSS/RTT。这是一个较小的值,大部分的带宽还是空闲的,如何迅速更新cwnd以提高带宽利用率??

  慢启动状态:cwnd的值以1个MSS开始并且每当传输的报文段首次被确认就增加一个MSS。

  • 刚开始在第一个RTT中,cwnd只有1个MSS,发送一个报文;
  • 收到一个ACK,此时cwnd增加1个MSS,在第2个RTT,cwnd为2个MSS,发送两个报文;
  • 会收到两个ACK,此时cwnd增加2个MSS,所以在第3个RTT中,cwnd为4个MSS,发送4个报文;
  • 依次类推。

  从上面的过程,不难发现每过一个RTT,发送速率就会翻一倍。虽然起始速率只有MSS/RTT,但是在慢启动的过程中是以指数增长的。当然,带宽是有限的,发送速率不可能无限制地增长,那么问题来了,什么时候结束这种指数增长??

  (1) 当有一个超时引起的丢包事件(拥塞)时,TCP发送方将cwnd设置为1并重新开始慢启动过程;同时将慢启动阈值ssthresh设置为cwnd/2。

  (2) 在(1)重新慢启动过程中,当cwnd的值增长到大于等于慢启动阈值ssthresh时,慢启动结束,同时转移到拥塞避免模式

   (3) 如果在慢启动的过程中,发送方收到3个冗余的ACK,TCP就结束慢启动过程,执行快速重传并进入快速恢复模式

2、拥塞避免

  上面说到,只有当再次启动慢启动并且cwnd增长到大于等于慢启动阈值ssthresh时,才会进入拥塞避免模式,所以当进入到拥塞避免时,cwnd的值大概是在第一次遇到拥塞时的cwnd的值的一半。此时如果继续进行慢启动就会使cwnd的值翻倍从而可能导致拥塞。所以拥塞避免模式对于每次收到的ACK,并不像慢启动那样直接将cwnd增加一个MSS字节,而是增加MSS*MSS/cwnd字节。也就是说当MSS=1460字节,cwnd为14600字节,那么每次收到一个ACK,cwnd增加1460*1/10字节,只有收到10个ACK,cwnd才会增加一个MSS。

  问题来了,与慢启动一样,难道cwnd的值也是这么一直增长下去么??什么时候结束呢?

  (1) 当有一个超时引起的丢包事件(拥塞)时,同慢启动一样,TCP发送方将cwnd设置为1并重新开始慢启动过程;同时将ssthresh设置为cwnd/2。

   (2) 当收到3个冗余的ACK时,ssthresh设置为cwnd/2,TCP将cwnd的值设置为ssthresh+3进入快速恢复模式

3、快速恢复

  对于引起TCP进入快速恢复状态的缺失报文段,对收到的每个冗余ACK,cwnd的值增加1个MSS,当收到新的ACK时TCP把cwnd设置为ssthresh的值进入拥塞避免状态

  当在快速恢复阶段出现超时事件,cwnd的值被设置为1个MSS,并且ssthresh的值设置为cwnd的一半,进入慢启动状态

  TCP的拥塞控制其实是加性增、乘性减(AIMD)的拥塞控制方式,当TCP连接的路径上没有拥塞(通过判断丢包事件)时,发送速率加性增;当出现丢包事件时,发送速率乘性递减。我们知道UDP本身是没有实现拥塞控制的,其实如果大量使用UDP而没有任何约束,那么网络就很容易出现死锁,使得端到端之间很少有数据能够被传输。

4、总结:

  当然,虽然UDP是不可靠、无连接的传输层协议,而TCP是面向连接的提供可靠数据传输的传输层协议。但是UDP的应用依旧很广,像DNS,QQ都是用的是UDP,很多人会奇怪,为什么TCP提供了那么多服务,为什么不用TCP而用这么不可靠的UDP呢??

  其实无论TCP还是UDP,在如此复杂的网络中,并不可能是完全可靠的。

  • TCP只是通过确认和重传机制来保证它的可靠性,而UDP并没有确认和重传机制。
  • TCP提供有序的数据流服务,UDP每个数据包是单独的,在接收方并不保证提交给应用层的数据包是有序的。
  • TCP提供流量控制和拥塞控制,通过流量控制,可以让发送方和接收方的应用层从接收缓冲区读取数据的速率匹配,从而不会因为接收缓冲区满而发生丢包;通过拥塞控制,每一个通过拥塞链路的TCP连接都能够平等地共享链路带宽。

  但是正因为TCP提供了这么多的服务,使得TCP变得很臃肿,很难发送大容量的数据;这时候,轻量的传输层协议UDP就站出来了。UDP很简单,不提供那么多的机制和服务,使得UDP的传输速率可以比TCP快很多。当然有人会说,UDP丢包率很高,UDP接收到无序的数据包,UDP没有拥塞,可能导致网络瘫痪等等一些问题。

  因为传输层及以上的层次都是只在端系统中实现的,在网络分组交换机中只有网络层一下的实现,也就是说TCP的所有这些服务都是基于端到端的服务。既然是端到端的服务,那么上述的所有问题都可以通过上层(也就是应用层)来实现,通过在应用层把发送的数据进行编号,就可以在接收端对接收的数据进行排序,从而的到有序的数据;通过在应用层添加确认和重传,就可以大大降低丢包率;通过在应用层加一个窗口,来达到流量控制和拥塞控制的目的。当然具体基于UDP的实现其实并不需要把所以TCP的服务都在应用层实现,否则还不如用TCP。我们只需要实现那些我们需要和关系的服务即可,比如说我们需要降低丢包率,我们就只实现重传机制。(当然我们也可以完全不用传输层,应用层直接通过网络层通信)

  UDP很自由,可以任由上层来实现;TCP很全面,可以给上层提高可靠的数据传输和各种机制。到底选择哪一种传输层协议,其实还要根据具体的应用来选择。存在既有价值,关键是各方面的权衡而已。

版权所有,欢迎转载,转载请注明出处。

深入理解TCP(二)的更多相关文章

  1. ppp 完全理解(二)【转】

    转自:https://blog.csdn.net/tianruxishui/article/details/44057717 ppp 完全理解(二) pppd 协议及代码分析 作者:李圳均 日期:20 ...

  2. 结合Wireshark捕获分组深入理解TCP/IP协议栈

    摘要:     本文剖析了浏览器输入URL到整个页面显示的整个过程,以百度首页为例,结合Wireshark俘获分组进行详细分析整个过程,从而更好地了解TCP/IP协议栈.   一.俘获分组 1.1 准 ...

  3. 简单理解TCP/IP协议

    一.什么是TCP/IP TCP/IP是一个协议族,是因为TCP/IP协议包括TCP.IP.UDP.ICMP.RIP.TELNETFTP.SMTP.ARP.TFTP等许多协议,这些协议一起称为TCP/I ...

  4. 深入理解TCP建立和关闭连接

    建立连接: 理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包含了自 ...

  5. 深入理解OOP(二):多态和继承(继承)

    本文是深入浅出OOP第二篇,主要说说继承的话题. 深入理解OOP(一):多态和继承(初期绑定和编译时多态) 深入理解OOP(二):多态和继承(继承) 深入理解OOP(三):多态和继承(动态绑定和运行时 ...

  6. C++ 中类的构造函数理解(二)

    C++ 中类的构造函数理解(二) 写在前面 上次的笔记中简要的探索了一下C++中类的构造函数的一些特性,这篇笔记将做进一步的探索.主要是复制构造函数的使用. 复制构造函数 复制构造函数也称拷贝构造函数 ...

  7. Java 反射理解(二)-- 动态加载类

    Java 反射理解(二)-- 动态加载类 概念 在获得类类型中,有一种方法是 Class.forName("类的全称"),有以下要点: 不仅表示了类的类类型,还代表了动态加载类 编 ...

  8. 如何理解TCP的三次握手协议?

    • TCP是一个面向链接的协议,任何一个面向连接的协议,我们都可以将其类比为我们最熟悉的打电话模型. 如何类比呢?我们可以从建立和销毁两个阶段分别来看这件事情. 建立连接阶段 首先,我们来看看TCP中 ...

  9. 【PHPsocket编程专题(理论篇)】初步理解TCP/IP、Http、Socket.md

    前言 我们平时说的最多的socket是什么呢,实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API).那TCP/IP又是什么呢?TCP/IP是ISO/OS ...

随机推荐

  1. 【循序渐进学Python】15.网络编程

    Python 内置封装了很多常见的网络协议的库,因此Python成为了一个强大的网络编程工具,这里是对Python的网络方面编程的一个简单描述. 1. 常用的网络设计模块 在标准库中有很多网络设计相关 ...

  2. jQuery TimeCircles 倒计时

    在线实例 默认 倒计时 使用方法 <h1 style="margin: 40px; font: 32px Microsoft Yahei; text-align: center;&qu ...

  3. 高性能javascript学习笔记系列(3) -DOM编程

    参考 高性能javascript 文档对象模型(DOM)是独立于语言的,用于操作XML和HTML文档的程序接口API,在浏览器中主要通过DOM提供的API与HTML进行交互,浏览器通常会把DOM和ja ...

  4. PHP 后台定时循环刷新某个页面 屏蔽apache意外停止

    PHP 后台定时循环刷新某个页面 如果间隔时间过长的话  会出现apache自动停止的现象.出现的原因则是设置了 <IfModule mpm_winnt_module> ThreadsPe ...

  5. JavaScript中with语句的理解

    with语句的作用是暂时改变作用域链.减少的重复输入. 其语法结构为: with(object){ //statements } 举一个实际例子吧: with(document.forms[0]){ ...

  6. DataGridView 设置某个列为只能为数字

    public DataGridViewTextBoxEditingControl CellEdit = null; int idx = 1; private void dataGridView1_Ed ...

  7. Web安全攻防-----TCP/IP安全篇

    知识点: 掌握TCP/IP的体系分层结构 掌握TCP/IP的各一层功能特点 掌握TCP/IP的数据在各层的名称 掌握TCP/IP的体系数据的封装和解封装 1.TCP/IP协议的历史 TCP/IP的起源 ...

  8. GPS定位为什么要转换处理?高德地图和百度地图坐标处理有什么不一样?

    GPS定位为什么要转换处理?高德地图和百度地图坐标处理有什么不一样? 先了解一下 高德地图 采用: GCJ-02 (不可逆) 百度百科: http://baike.baidu.com/link?url ...

  9. 一个巧妙的实现悬浮的tableViewHeader的方法

    之前因为工作需要要实现一个类似的 悬浮+视差的headerView的效果, 研究了好久没研究出来怎么做,最后用UICollectionView + CSStickyHeaderFlowLayout的方 ...

  10. zookeeper入门讲解事例

    zookeeper使用和原理探究(一) zookeeper介绍zookeeper是一个为分布式应用提供一致性服务的软件,它是开源的Hadoop项目中的一个子项目,并且根据google发表的<Th ...