深入理解TCP(二)
上一篇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(二)的更多相关文章
- ppp 完全理解(二)【转】
转自:https://blog.csdn.net/tianruxishui/article/details/44057717 ppp 完全理解(二) pppd 协议及代码分析 作者:李圳均 日期:20 ...
- 结合Wireshark捕获分组深入理解TCP/IP协议栈
摘要: 本文剖析了浏览器输入URL到整个页面显示的整个过程,以百度首页为例,结合Wireshark俘获分组进行详细分析整个过程,从而更好地了解TCP/IP协议栈. 一.俘获分组 1.1 准 ...
- 简单理解TCP/IP协议
一.什么是TCP/IP TCP/IP是一个协议族,是因为TCP/IP协议包括TCP.IP.UDP.ICMP.RIP.TELNETFTP.SMTP.ARP.TFTP等许多协议,这些协议一起称为TCP/I ...
- 深入理解TCP建立和关闭连接
建立连接: 理解:窗口和滑动窗口TCP的流量控制TCP使用窗口机制进行流量控制什么是窗口?连接建立时,各端分配一块缓冲区用来存储接收的数据,并将缓冲区的尺寸发送给另一端 接收方发送的确认信息中包含了自 ...
- 深入理解OOP(二):多态和继承(继承)
本文是深入浅出OOP第二篇,主要说说继承的话题. 深入理解OOP(一):多态和继承(初期绑定和编译时多态) 深入理解OOP(二):多态和继承(继承) 深入理解OOP(三):多态和继承(动态绑定和运行时 ...
- C++ 中类的构造函数理解(二)
C++ 中类的构造函数理解(二) 写在前面 上次的笔记中简要的探索了一下C++中类的构造函数的一些特性,这篇笔记将做进一步的探索.主要是复制构造函数的使用. 复制构造函数 复制构造函数也称拷贝构造函数 ...
- Java 反射理解(二)-- 动态加载类
Java 反射理解(二)-- 动态加载类 概念 在获得类类型中,有一种方法是 Class.forName("类的全称"),有以下要点: 不仅表示了类的类类型,还代表了动态加载类 编 ...
- 如何理解TCP的三次握手协议?
• TCP是一个面向链接的协议,任何一个面向连接的协议,我们都可以将其类比为我们最熟悉的打电话模型. 如何类比呢?我们可以从建立和销毁两个阶段分别来看这件事情. 建立连接阶段 首先,我们来看看TCP中 ...
- 【PHPsocket编程专题(理论篇)】初步理解TCP/IP、Http、Socket.md
前言 我们平时说的最多的socket是什么呢,实际上socket是对TCP/IP协议的封装,Socket本身并不是协议,而是一个调用接口(API).那TCP/IP又是什么呢?TCP/IP是ISO/OS ...
随机推荐
- 通过Google身份验证器加强Linux帐户安全
下载Google的身份验证模块: # wget https://google-authenticator.googlecode.com/files/libpam-google-authenticato ...
- 【转】从MVC到前后端分离
1. 理解MVC MVC是一种经典的设计模式,全名为Model-View-Controller,即模型-视图-控制器. 其中,模型是用于封装数据的载体,例如,在Java中一般通过一个简单的POJO(P ...
- 15款最好的 jQuery Modal(模态窗口)插件
jQuery 模态窗口插件帮助网站开发人员显示网页中的特定内容,让用户聚焦到这个地方.模态窗口是嵌入到当前网页中,不用重定向到新网页的弹出窗口.这种技术可以用在图像画廊,电子商务网站,登陆框,电子邮件 ...
- iOS 判断数组是否为空
有人说可以用([array count]==0 )来判断是否为空,都是坑,如果array为空的话,执行count就会直接报错,程序崩溃退出. 正确判断NSArray是否为空的方法:用 (!array) ...
- SharePoint 2013 WebPart 管理工具分享[开源]
前言 之前做门户的时候,经常要导入导出WebPart,非常的频繁,然后就需要一个个导出,然后一个个导入,非常繁琐:闲暇之际,就考虑能不能自动化一下,把这个功能写成一个工具,可以方便的管理WebPart ...
- assign,copy,strong,weak,nonatomic的理解
举个例子: NSString *houseOfMM = [[NSString alloc] initWithString:'MM的三室两厅']; 上面一段代码会执行以下两个动作: 1 在堆上分配一段 ...
- 最全面的NSDateHelper 分享
NSDateUtil 分享 (ios开发交流群:486468672) 代码下载:https://github.com/foxswang/NSDateUtil 史上最全面NSDate Utility 没 ...
- popover带箭头弹框
我们先来看一下效果吧: 分析:这个带箭头的弹框其实是一个控制器,通过Modal方式展现,但跟传统模态方式效果不一样,我们一眼就能看出. Xib方式实现popover: 1.segue的时候选择Pres ...
- ParagraphString - 段落样式的简易处理
ParagraphString - 段落样式的简易处理 效果 源码 https://github.com/YouXianMing/UI-Component-Collection 中的 Paragrap ...
- sqlite 增删改查
PersonDao1.java package mm.shandong.com.testsqlsqllite.dao; import android.content.Context; import a ...