【转】TCP/IP 系列之 TCP 流控与拥塞控制(一)

原文地址:http://mrpeak.cn/blog/tcp-flow-control00/

TCP/IP 系列之 TCP 流控与拥塞控制(一)

TCP 流控(flow control)与拥塞控制(congestion control),是我个人认为每个 iOS 工程师都应该熟悉的,价值含量极高的知识点。明白了三次握手,但是不了解流控和拥塞控制背后的设计原理,是不能够在简历上写「精通 tcp/ip」的。

Flow control 和 congestion control 的学习价值高,而且学习过程也会很有趣。掌握整个过程的意义,远超过学习 TCP 协议本身。

不少工程师在工作三五年之后,会尝试提升代码抽象和设计的能力,有些会刻意去读一些架构或者设计方面的书、文章,早些年的时候,流行研究 GOF 的 Design Patterns。这是一个方向,但我个人觉得,更高效可行的方法是研究经典的计算机问题。经典问题里所包含的设计思路,模块划分方式,架构处理等等,都凝结了无数前辈的智慧,理清楚整个流程,再扒一扒设计的细节,抽象的能力会自然而然的随之提升,这是内功心法方面的积累,比记住几个设计模式如何使用,意义要大的多。

TCP 流控和拥塞控制就是这样一个经典的计算机问题。流控机制和拥塞控制机制,也是学习 TCP 协议栈的精华所在。这两个机制又各自包含一系列其他设计,比如 sliding window,stop and wait,retransmission policies 等等。

首先我们要分清楚 flow control 和 congestion control 的区别,这也是很多初学者容易混淆的概念。

Flow control 是站在单条 TCP 连接的维度,目的是让发送方发包的速度,不超过接收方收包的能力,所以 flow control 解决的问题是,如何在接收方可承受的范围内,让单条 TCP 连接的速度最大化。

Congestion control 则是站在整个互联网的维度,让网络里所有 TCP 连接最大化共享网络通道的同时,尽可能的少出现网络拥塞现象,让网络世界里的每一个参与者既公平又高效。

这就是他们的区别所在,但由于二者在学习的时候存在很多交叉的概念,极容易混淆,这也是为什么这篇文章会将这二者先放到一起讨论,明白各自所针对的问题域,再深入细化学习,这样知识掌握才会牢固。

之前的文章里提到过,所谓一个 TCP 连接可以看做是一个完整的字节流。Byte stream 就像自来水管里的水,在流量大的时候,会把网络通道充满,管道满了,有些 bit 就只能等待,等待的过长,就会超时,丢包率跟着上去,网络环境自然就变差啦。大家平时使用宽带,一到晚上就感觉网速下降,其实网速并没有变化,只不过由于人多了,流量变大,而管道容量有限,每个人能分到的流量就有限了。

也就是说,互联网发展到今天,其基础设施建设,相对于需求,仍处于供不应求的状态。这还是在 TCP 协议做了巧妙的流控和拥塞控制之后,如果没有这些机制,根本无法想象今天的互联网究竟会是怎样一种体验。

拥塞控制

我们先来看看 congestion control,里面谈到的一些概念 flow control 中也会出现。拥塞控制的目的是,让互联网世界里的每一个 TCP 连接都能高速的沟通,同时又以最文明的方式,尽可能的不去占用过多的管道资源。

如果让你来设计,你会怎么做呢?

慢启动(slow start)

congestion control 的第一步就是慢启动,通信的双方在建立连接的时候,先慢慢的发包。比如我们可以先让发送方发一个包,等这个包被 ack 之后,我们再发 2 个包,这 2 个被 ack 之后再发 4 个包,以此类推,让一次所发的包数量慢慢增加,这就是慢启动。打个比方,这个过程非常像大家使用自来水时,慢慢拧开水龙头。

为什么要这么做?为什么不在一开始就猛的拧开水龙头?一开始就大流量发包,这样对一条 TCP 连接来说是快了,但大家都这么做,整个互联网世界里的就很容易出现瞬时的暴增,带宽资源的分配就难以合理均衡,拥塞现象更容易发生。而慢启动,就是让每一个 TCP 连接做个文明的绅士,慢慢的拧开水龙头,只有在双方成功建立一个健康的连接,且存在的大流量发包需求的时候,才将流量提升上去。

和 TCP 的慢启动相比,UDP 显得非常不文明,UDP 会在连接的一开始,就将流量开至最大,这也是为什么现在有不少基于 UDP 的类 TCP 方案,可以避免 TCP 慢启动所带来的影响,这种做法虽然高效却不值得称赞,是对现有公平秩序的破坏,所以有些运营商会对大流量的 UDP 采取惩罚措施。

慢启动的影响确实会比较大,它不仅仅发生在建立连接的初期。一条 TCP 通道在健康通讯一段时间之后,如果丢包率突然上去,导致大量的包发送超时,Slow start 有可能会被重新启动,这也是为什么有时候明明带宽足够,如果丢包率过高(网络不稳定),网速却上不去。

我们再深入看一下 slow start 的细节和一些基础概念。

为了简化学习模型,我们假设一条 TCP 通道里,一方只发送,另一方只接收,当然一般实际场景里,任何一方既是发送者又是接受者。

Window

谈 TCP 离不开 window 的概念,有 congestion window,receive window,sliding window 等等。window 是以 tcp segment 数量为单位,我们可以说当前 window 值由几个 tcp 包构成,而当我们说 window size 的时候,又是在说一个 window 所包含的字节数。window size 除了和 tcp segment 的数量有关之外,还和单个 tcp segment 的最大 size 有关,即 MSS 值。

MSS

MSS 值,即 maximum segment size,是单个 TCP 包所包含的最大字节数。我们之所以要限制单个 TCP 包的大小,是受限于 TCP/IP 协议栈更下层的 MTU 值,至于 MTU 是啥,就留给读者自己去扒了,MTU 也是非常重要的概念。

发送方和接收方通讯的时候,会采用一个共同的 MSS 值,这个 MSS 值是取发送方 MSS 和 接收方 MSS 二者的较小值,一般是 1460,刚才提到的 MTU 值一般是 1500,大家可以扒一扒二者的关系。

SMSS

发送方的 MSS 值即为 SMSS(Sender’s MSS),这个值要单独拿出来说,是因为和下面的 CWND 相关。

CWND 和 RWND

发送方的 Window 大小称之为 CWND(congestion window),接收方的 Window 大小称之为 RWND(receiver window,或者 advertised window)。CWND 表示当前发送方可以发送多少个 TCP 包,而 RWND 表示当前接收方还能接收多少个 TCP 包。

值得注意的是,CWND 是一个发送方本地的值,并不会在网络上传输。而 RWND 则是由接收方告知发送方的,是存在于 TCP 包的协议中,会通过网络传输。大家也可以自己研究下,RWND 在 TCP header 中是哪个字段,其大小又是如何计算的。

Transmission Window

Transmission window 的大小是真正表示,发送方可以一次发送多少个尚未被 ack 的包。这个值是一般先取 CWND 和 RWND 的较小值,之后会动态的调整变化,slow start 阶段会变化,congestion avoidence 发生时也会变化。

慢启动过程

连接刚开始建立的时候,发送方有一个初识的 CWND 值,这个值在一开始是由 SMSS 的值决定的,二者之间有一个简单的公式关系,可以参考 RFC 5681。这个初始值直接决定了一开始,发送方可以发送包的数量,这个值对于初期的性能影响比较大,发送的包越多,自然请求的响应也就越快。那么 CWND 的初始值到底是多少呢?

虽然 RFC 对于 CWND 的初始值有一个公式建议,但不同的 TCP 实现,initial CWND 值并不一样。有些云服务商为了提升性能,特意设置了一个较大的 CWND 值(比如 10 或者更大),这样在三次握手之后,立马就可以一次发送 10 个以上的 TCP 包。

我们假设发送方在三次握手,成功建立连接之后,一次先发送了 2 个 TCP 包,慢启动的规则是,每一个被 ack 的包,可以将 CWND 的值 +1。即是说,2 个 TCP 包被 ack 之后,发送方继而可以发送 4 个包,这 4 个又被 ack 之后,又能发送 8 个,以此类推,逐渐成倍的增加 CWND 值。

CWND 值会不会一直增加呢?显然不会,当通道的吞吐量达到一定量之后,CWND 的值就会受其他因素影响,比如进入 congestion avoidence 阶段,不过这是另一个话题啦。

慢启动就先介绍到这里,这篇文章的信息量也有不少了。

总结

TCP flow control 和 congestion control 涉及的知识点比较多,后面还会有更多的文章来介绍。大家也可以这两个大方向为 TCP 协议的学习框架,自己多去研究两种机制下的各种细节,如果能把整个流程烂熟于心,其义自见。

原文地址:https://www.cnblogs.com/jerain6312/p/10821085.html

时间: 2024-08-14 04:57:19

【转】TCP/IP 系列之 TCP 流控与拥塞控制(一)的相关文章

OSI七层模型与 TCP/IP五层模型 TCP/UDP的区别

转自:http://blog.chinaunix.net/uid-22166872-id-3716751.html OSI七层模型OSI 中的层            功能                                                        TCP/IP协议族 应 用层                 文件传输,电子邮件,文件服务,虚拟终 端         TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层          

TCP/IP 协议图--TCP/IP 基础

1. TCP/IP 的具体含义 从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议.实际生活当中有时也确实就是指这两种协议.然而在很多情况下,它只是利用 IP 进行通信时所必须用到的协议群的统称.具体来说,IP 或 ICMP.TCP 或 UDP.TELNET 或 FTP.以及 HTTP 等都属于 TCP/IP 协议.他们与 TCP 或 IP 的关系紧密,是互联网必不可少的组成部分.TCP/IP 一词泛指这些协议,因此,有时也称 TCP/IP 为网际协议群. 互联网进行

TCP/IP协议图--TCP/IP基础

1. TCP/IP 的具体含义 从字面意义上讲,有人可能会认为 TCP/IP 是指 TCP 和 IP 两种协议.实际生活当中有时也确实就是指这两种协议.然而在很多情况下,它只是利用 IP 进行通信时所必须用到的协议群的统称.具体来说,IP 或 ICMP.TCP 或 UDP.TELNET 或 FTP.以及 HTTP 等都属于 TCP/IP 协议.他们与 TCP 或 IP 的关系紧密,是互联网必不可少的组成部分.TCP/IP 一词泛指这些协议,因此,有时也称 TCP/IP 为网际协议群. 互联网进行

TCP/IP系列——长连接与短连接的区别

1 什么是长连接和短连接 三次握手和四次挥手 TCP区别于UDP最重要的特点是TCP必须建立在可靠的连接之上,连接的建立和释放就是握手和挥手的过程. 三次握手为连接的建立过程,握手失败则连接建立失败. 四次挥手为连接的完整释放过程,也会发生某个消息丢失或者超时的情况,有一方主动发送FIN消息即表示连接即将释放. 注:SYN.ACK.FIN消息具有哪些含义,以及连接的状态,请参考<TCP/IP详解 卷1>第18章. 长连接 长连接,也叫持久连接,在TCP层握手成功后,不立即断开连接,并在此连接的

TCP/IP具体解释--TCP/UDP优化设置总结&amp;amp; MTU的相关介绍

首先要看TCP/IP协议,涉及到四层:链路层,网络层.传输层,应用层. 当中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Data)在应用层 它们的关系是 数据帧{IP包{TCP或UDP包{Data}}} --------------------------------------------------------------------------------- 在应用程序中我们用到的Data的长度最大是多少,直接取决于底层的限

TCP/IP详细解释--TCP/IP可靠的原则 推拉窗 拥塞窗口

TCP和UDP在同一水平---传输层.但TCP和UDP最不一样的地方.TCP它提供了一个可靠的数据传输服务,TCP是面向连接的,那.使用TCP两台主机通过第一通信"拨打电话"这个过程,等待,直到通信结束就开始准备数据传输,最后,结束通话. 所以TCP比UDP可靠的多,UDP是把数据直接发出去.而无论对方是不是在收信,就算是UDP无法送达.也不会产生ICMP差错报文,这一经时重申了非常多遍了. 把TCP保证可靠性的简单工作原理摘抄例如以下 应用数据被切割成TCP觉得最适合发送的数据块.

TCP/IP模型及TCP/UDP协议

协议:为进行网络中的数据交换(通信)而建立的规则.标准或约定.(=语义+语法+规则) TCP/IP已成为Internet上通信的工业标准. TCP/IP模型: TCP协议是一个面向连接的可靠性传输协议,在发送数据之前,先要发出连接请求,当对方监听到有请求来到时就建立连接,然后双方就可以收发消息,发送完信息后,双方就断开连接(即三次握手协议). 三次握手协议: 第一次握手: 建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认:SYN:同步序列编号(Sy

[转]使用wireshark分析TCP/IP协议中TCP包头的格式

本文简单介绍了TCP面向连接理论知识,详细讲述了TCP报文各个字段含义,并从Wireshark俘获分组中选取TCP连接建立相关报文段进行分析. 一.概述 TCP是面向连接的可靠传输协议,两个进程互发数据之前需要建立连接,这里的连接只不过是端系统中分配的一些缓存和状态变量,中间的分组交换机不维护任何连接状态信息.连接建立整个过程如下(即三次握手协议): 首先,客户机发送一个特殊的TCP报文段: 其次,服务器用另一个特殊的TCP报文段来响应: 最后,客户机再用第三个特殊报文段作为响应. 图1 三次握

TCP/IP具体解释--TCP的分段和IP的分片

写在前面: 分组能够发生在运输层和网络层.运输层中的TCP会分段,网络层中的IP会分片.IP层的分片很多其它的是为运输层的UDP服务的,因为TCP自己会避免IP的分片,所以使用TCP传输在IP层都不会发生分片的现象. 我们在学习TCP/IP协议时都知道.TCP报文段假设非常长的话,会在发送时发生分段.在接受时进行重组,相同IP数据报在长度超过一定值时也会发生分片,在接收端再将分片重组. 我们先来看两个与TCP报文段分段和IP数据报分片密切相关的概念. MYU(最大传输单元) MTU前面已经说过了