目录
-
-
- 第五章 传输层
-
- 5.1 传输层概述
-
- 进程之间的通信
- 网络层与传输层的区别
- 传输层的两个主要协议
- 传输层的端口
- TCP/IP传输层端口
- 5.2 UDP
-
- UDP需要实现的功能
- UDP提供的服务
- UDP适合哪些应用
- UDP协议的特点
- UDP基于端口的分用
- UDP报文的首部格式
- 5.3 TCP概述
-
- TCP最主要的特点
- TCP面向流的概念
- TCP的连接
- Socket不同的含义
- 5.4 TCP报文格式
-
- TCP报文段的首部格式
- 为什么要规定MSS
- 其他选项
- 5.5 可靠传输的工作原理
-
- 理想的传输条件特点
- 停止等待的协议
- 自动重传请求ARQ
- 信道利用率
- 流水线传输
- 连续ARQ协议
- TCP可靠通信的具体实现
- 5.6 TCP可靠传输的实现
-
- 以字节为单位的滑动窗口
- 发送缓存
- 发送缓存与接收缓存的作用
- 接收方发送确认
- 超时重传时间的选择
- 如何设置超时值
- 加权平均往返时间
- 超时重传时间RTO
- TCP确认的二义性
- Karn算法
- 修正的Karn算法
- 选择确认SACK
- RFC 2018的规定
- 5.7 TCP的流量控制
-
- 利用滑动窗口实现流量控制
- 零窗口特例下死锁的解决
- TCP的传输效率
- 发送方糊涂窗口综合征
- Nagle算法
- 接收方糊涂窗口综合征
- TCP流量控制小结
- 5.8 TCP的拥塞控制
-
- 拥塞控制的一般原理
- 网络拥塞产生的后果及原因
- 拥塞控制所起的作用
- 开环控制和闭环控制
- 监测网络拥塞的指标
- TCP的拥塞控制方法
- 网络拥塞的判断依据
- TCP拥塞控制算法
- 拥塞窗口的调节策略:AIMD
- TCP拥塞控制流程图
- 发送窗口的上限值
- 5.9 TCP的传输连接管理
-
- 传输连接的三个阶段
- 连接建立前的准备
- TCP的三次握手
-
第五章 传输层
5.1 传输层概述
传输层架构在网络层形成的服务之上,把数据传输服务从两台计算机之间扩展到两台计算机上的进程之间,网络层提供尽力而为的服务,而传输层是有所为有所不为。
传输层提供进程之间本地通信的抽象模式,即运行在不同终端上的应用进程仿佛是直接连接在一起的。
进程之间的通信
传输层介乎于应用层和网络层之间,向上为应用层提供通信服务,属于面向通信部份的最高层,同时也是用户功能中的最低层,当网络边缘的两个主机使用网络核心部分的功能进行端到端的通信时,只有位于网络边缘的协议栈才有传输层,也就是说网络核心部分的路由器在转发分组时只用了下三层的功能。
严格来讲,两台主机进行通信就是两台主机中运行的进程相互通信,从传输层的角度看,通信的真正端点其实并不是主机本身,而是主机中的进程。
网络层与传输层的区别
网络层是为主机之间提供逻辑通信,通信所用到的关键参数是IP地址,包括源地址和目标地址,而传输层是为应用进程之间提供端到端的逻辑通信,其所需要的关键参数除了IP地址外还需要传输协议及端口号。
而传输层的作用体现在一台主机中经常会有多个应用进程同时分别和另一台主机中的多个应用进程进行通信,这种情况下传输层有一个很重要的功能:复用和分用。
复用是指在发生方不同的应用进程都可以使用同一传输协议,通过增加适当的首部传送数据,分用是指接收方的传输层在剥去报文的首部后能够把这些数据正确交付到目的应用进程,另外传输层对接收到的报文进行差错检测,在网络层的IP数据报首部中存在着校验和字段,但其只对首部的差错进行校验,不会对报文本身内容进行校验。根据应用层的不同需求,传输层需要有两种不同的协议:面向连接的TCP和无连接的UDP。
传输层可以为高层用户建立一条端到端的逻辑通信信道,上层协议不同信道也有很大的差别。当传输层采用TCP协议时,逻辑信道采用全双工可靠信道,当使用无连接的协议时,逻辑信道采用不可靠信道。
传输层的两个主要协议
- 用户数据报协议UDP:传送单位是UDP报文或用户数据报,是一种无连接协议,可提供进程到进程之间的报文交付或报文检错
- 传输控制协议TCP:传送单位是TCP报文段,面向连接的协议,不提供广播或多播服务,因为要提供可靠的传输服务因此增加了许多开销
传输层的端口
- 硬件端口:路由器或交换机上的端口
- 软件端口:在协议栈层间的抽象的协议端口
端口号只具有本地意义,即端口号只是为了标记本计算机应用的进程,在互联网中不同计算机的端口号是不互相关联的。两个计算机要互相通信,不仅要知道对方的IP地址(为了找到计算机),还要知道对方计算机的端口号,这样就可以找到对方计算机中的应用进程。
TCP/IP传输层端口
-
服务器使用的端口号
包括熟知端口,也就是系统的端口号,数值通常为0-1023,还有登记端口,数值通常为1024-49151,为没有数值端口号的程序使用,使用这个端口号必须在IANA登记,以防止端口重复使用
-
客户端使用的端口号
又称为短暂端口号,数值在49152-65535,留给客户进程选择暂时使用,该端口属于动态端口范围,没有端口可以被正式地注册占用,当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号,通信结束后这个端口号可提供其他客户以后使用
常用的熟知端口:
5.2 UDP
UDP需要实现的功能
UDP只在IP的数据服务基础上增加了很少的一点功能——复用和分用的功能,报文和差错检错的功能
UDP提供的服务
UDP在网络服务的基础上提供进程到进程的报文交付服务以及可选的完整检查性服务
UDP适合哪些应用
能容忍丢包但对延迟敏感的应用,以单次响应为主的应用
UDP协议的特点
-
UDP是无连接的
发送数据之前不需要建立连接,因此减少了开销和发送数据之前的时延
-
UDP使用尽最大努力交付
不保证可靠交付,因此主机不需要维持复杂的连接状态表
-
UDP是面向报文的
UDP对应用层下来的报文既不合并,也不拆分,而是保留这些报文的边界,UDP以此交付一个完整的报文
-
UDP没有拥塞控制
网络出现拥塞不会使源主机发送速率降低
-
UDP支持多种交互通信方式:一对多,多对一
-
UDP首部开销小
UDP对应用层的报文只添加UDP首部便向下交付,一次交付一个报文,当接收方收到到网络层的报文后,除去首部向上交付,一次交付一个报文,应用程序必须选择合适大小的报文,若报文太长UDP把它交付给IP层,IP层再传输时可能要进行分片,这会降低IP层的传输效率。
UDP基于端口的分用
当传输层从IP层收到UDP数据报时,就根据首部的目的端口把UDP数据报分别转向相应端口,上交到最终的终点,如果接收方UDP收到的目的端口不正确,就丢弃该报文,并由ICMP发送端口不可达的差错报文给发送方。
UDP报文的首部格式
UDP报文有两个字段,首部字段有8个字节,共有四个字段组成,每个字段都是两个字节,UDP报文的报头是携带协议所处理需要的信息,载荷部分是携带上层的数据,对应用于复用和分用的字段是源端口号和目的端口号,用于检测报文错误的字段包括了报文总长度及校验和。
UDP校验和字段的作用:对传输的报文段进行检错。
在计算校验和的时候,把UDP用户数据报之前的12个字节作为伪首部,临时把伪首部和UDP用户数据报连接在一起,仅仅是为了计算校验和。伪首部其实是IP报文首部的一部分,包括源IP地址,目的IP地址,1字节的全0字段,协议字段数值为17,及UDP的长度字段。
5.3 TCP概述
TCP最主要的特点
- TCP是面向连接的传输层协议,会有连接的建立与释放的过程
- 每一条TCP连接只能由两个端点,也就是一对一的
- TCP提供可靠交付的服务,流水线式发送,无差错,无丢失,不重复且能够按序到达
- TCP提供全双工通信的方式,两端都设有发送和接收缓存且实现流量控制
- TCP是面向字节流的。TCP中的流指的是流入或流出进程的字节序列。面向流的含义是虽然应用程序和TCP的交互是一次一个数据块,但TCP把应用层交下来的数据看成仅仅是一串无节奏的字节流
TCP面向流的概念
TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发送的数据块大小具有一一对应的关系,但接收方应用程序收到的字节流必须是和发送方应用程序发出的字节流完全一样,TCP不关心应用进程一次把多长的报文发送到TCP的缓存中,而TCP对连续的字节流根据当前网络环境因素进行分段,形成TCP报文段实现数据传输。TCP的连接是一条虚连接,而不是一条真正的物理连接,TCP根据对方给出的窗口值和当前网络拥塞的程度来决定一个报文段应包含多少个字节,而UDP发送的报文段是完全由应用进程所确定的。TCP可把太长的数据块分段再传送,也可等待足够多的字节构成报文段再发送。
TCP的连接
TCP把连接作为最基本的抽象,每一条TCP连接有两个端点,TCP连接的端点不是主机,不是主机的IP地址,不是应用进程,也不是传输层的协议端口,TCP连接的端口被称作套接字或插口,把端口号拼接到IP地址就构成了套接字。
每一条TCP连接唯一地被通信两端的两个端点(即两个套接字)所确定。
TCP连接就是由协议软件所提供的一种抽象,TCP连接的端点是个很抽象的套接字:
套接字 socket = (IP地址:端口号)
TCP连接::={socket1,socket2}={(IP1:port1),(IP2:port2)}
Socket不同的含义
- 应用编程接口API
- socket API中的一个函数名
- 调用socket函数的端点称为socket
- 调用socket函数时其返回值
- 在操作系统内核中socket实现的概念
以上均与本节所提及的套接字不同
5.4 TCP报文格式
TCP报文段的首部格式
图中每行是4个字节,32位,TCP是面向字节流的,但TCP传输的单位却是报文段,一个TCP报文段分为首部和数据两部分,而TCP的全部功能都体现在它首部中各字段的作用。
TCP报文段中前20个字节是固定的,后面有4*n个字节是根据需要而增加的选项字段,n是个整数,最长是40个字节,因此TCP首部的长度是20-40个字节之间。
- 第一行是源端口和目的端口字段,各占2个字节。端口是传输层和应用层的服务接口,传输层的复用和分用功能都要通过端口才能实现。
- 第二行是序号字段,占4个字节。TCP连接中传输的数据流每一个字节都编上了序号,序号字段的值实际是指的本报文段中所发送的数据的第一个字节的序号
- 第三行是确认号字段,占4个字节。是期望收到对方的报文段数据的第一个字节序号。
- 数据偏移字段,即首部长度,它占了四位,指出了TCP报文段的数据起始处距离TCP报文段的起始处有多远,数据偏移的单位是32位字。以4字节长的字为计算单位,最大的数值是60字节
- 保留字段,占6位,保留位今后使用,目前都把它设置为0
- 紧急标志URG,当URG=1时,表明紧急指针字段有效,它高速系统此报文段中有紧急数据,应尽快传送,相当于是一个高优先级的数据
- 确认标志ACK,只有当ACK=1,确认号字段才有用,当ACK=0时确认号无效
- 推送标志PSH,接收TCP收到PSH=1的报文段,就尽快地交付接收应用进程,不再等到整个缓存填满了再向上交付
- 复位标志RST,当RST=1时表明TCP连接中出现了严重的差错,如主机崩溃或其他的原因,此时必须释放连接然后再重新建立连接
- 同步标志SYN,SYN=1表示这是一个连接请求或连接接受报文,与ACK标志配合实现
- 终止标志FIN,它是用来释放一个连接的,FIN=1表明此报文段中的发送数据已经发送完毕并要求释放传输连接
- 窗口字段占了2个字节,作为接收方让发送方设置发送窗口的依据,单位为字节,窗口指经常在动态变化着,此字段明确指出现在允许对方发送的数据量
- 检验和字段占两个字节,检验范围为首部和数据两个部分,在计算检验和时要在TCP报文段前加上12位伪首部
- 紧急指针字段占16位,指出在本报文段中紧急数据有多少个字节,紧急数据放在本报文段的最前端,它只当URG=1时才有效
- 选项字段长度可调,最长40个字节,TCP最初只规定了一种选项,即最大报文段长度MSS,MSS告诉对方TCP我的缓存所能接受的报文的最长字段是MSS个字节,而MSS是TCP报文段中的数据字段的最大长度,数据字段加上TCP首部等于整个TCP的报文段,所以MSS的长度是TCP报文长度减去首部长度。
- 填充字段,为了使整个首部长度为4的整数倍
为什么要规定MSS
设置合理的MSS数值,可以提高网络利用率,减小额外开销,在建立连接时,双方都把自己能够支持的MSS写入字段,传送数据时就以此为准,两个方向可以采用不同的MSS,MSS的默认值是536字节,即所有互联网都能够接受的长度是536+20即556个字节。MSS的选择应尽可能大些,只要在IP层传输时不需要再分片就行。
其他选项
- 窗口扩大选项,占3字节,其中有一个字节表示移位值S,新的窗口值等于TCP首部的窗口位数增大到16+S,相当于把窗口值向左移动S位后获得的窗口值,移位值允许使用的最大值是14,窗口的最大数值可以增大到230-1
- 时间戳选项占10字节,其中最主要的字段是时间戳值字段(4字节)和时间戳回送回答字段(4字节),它们通常是用来计算往返时间RTT和用来处理TCP序号超过22的情况,防止序号绕回这种情况
- 选项确认选项
5.5 可靠传输的工作原理
理想的传输条件特点
- 传输信道无差错
- 不管发送方以多快的速度发送数据,接收方总是来得及处理收到的数据
停止等待的协议
每发送完一个分组就停止发送,等待对方的确认,当收到确认后再发送下一个分组。全双工通信的双方既是发送方又是接收方,为了讨论问题的方便,我们在后面仅考虑A发送数据,B接受数据并发送确认,因此A叫做发送方,B叫做接收方,我们分情况来讨论。
- 无差错情况
A向B发送数据M1,B确认收到后A继续发送M2
- 出现差错
B检测M1时检测到差错,就直接丢弃M1,其他什么都不做,也不会通知A收到了有差错的分组;如果M1在传输过程中丢失了,B当然什么也不知道,就什么都不做。
A为每一个已发送的分组都设置了一个超时计时器,A只要在超时计时器到期之前收到了相关的确认就撤销该超时计时器,继续发送下一个分组M2,反之则超时重传M1.
- 确认丢失和确认收到
A向B发送M1,B也收到了M1,但是B向A发送的确认收到丢失了,A并不能确定是自己没有将M1传给B还是B没有将确认报文传给自己,于是选择了重传,B此时收到再次发送来的M1要做两个动作,一个是丢弃这个重新发送过来的M1,并不把它交付给上层,二是再次向A发送确认报文表明自己接收到了M1报文。
B向A发送的确认报文迟到了,A仍然与确认丢失的情况一样对M1进行重传,此时B对重新发送的M1进行丢弃,并重新发送确认报文。
在发送完一个分组后,必须暂时保留已发送的分组的副本,以备重发,分组和确认分组都必须要进行编号。超时计时器的重传时间应当比数据在分组传输的平均往返时间RTT要更长一些。
自动重传请求ARQ
通常A最终总是可以收到对所有发出的分组的确认,如果A总是重传分组却收不到确认就表明通信线路质量太差,不能进行通信。
使用确认和重传机制,我们就可以在不可靠的传输网络上实现可靠的通信,而这种可靠传输协议常称为自动重传请求ARQ,意思是重传的请求是自动进行的,接收方不需要请求发送方重传某个出错的分组。
信道利用率
TD是发送分组所需要的时间,等于分组长度除以数据率,TA是B发送确认分组所需要的时间,RTT是往返时间,停止等待协议的优点是简单,缺点是利用率太低。
流水线传输
为了提高传输效率,发送方可以不使用低效率的停止等待协议,而是采用流水线传输,如图所示,流水线传输就是发送方连续发送多个分组,不必每发完一个分组就停下来等接收方确认,这样可使信道上一直有数据不间断地传送,这样可以获得很高的信道利用率。
连续ARQ协议
发送方维持的发送窗口意义在于位于发送窗口内的分组都可连续地发送出去,而不需要等待对方的确认,这样信道利用率就提高了。
连续ARQ协议规定发送方每收到一个确认,就把发送窗口向前滑动一个分组的位置
接收方一般采用累计确认的方式,即不必对收到的分组逐个发送确认,而是对按需到达的最后一个分组发送确认,这样就表示到这个分组为止的所有分组都正确收到了。它的优点是确认丢失,即使确认丢失也不必重传,缺点是不能向发送方反映出接收方已经正确收到的所有分组的信息,如果发送方发送了前五个分组,而中间的第三个分组丢失了,这时接收方只能对前两个分组发出确认,发送方无法知道后面三个分组的下落,只好把后面的三个分组都再重传一次,这就叫==Go-back-N(回退N),表示需要再退回来重传已发送的N个分组,可见当通信质量不好的时候连续ARQ协议会带来负面的影响。
TCP可靠通信的具体实现
TCP连接的每一端都必须要设置两个窗口,一个发送窗口和一个接收窗口,TCP的可靠传输机制是用字节的序号来进行控制的,TCP所有的序号都是基于序号的,TCP两端的四个窗口是动态变化的,TCP的往返时间RTT也不是固定不变的,需要算法来估算合理的重传时间。
5.6 TCP可靠传输的实现
以字节为单位的滑动窗口
如图,假定A收到了B发来的确认报文段,其中窗口是20字节,而确认号是31,这表明B期望收到的下一个序号是31,而序号30之前的数据已经收到,根据这两个数据,A就构造出了自己的发送窗口。发送窗口表示在没有收到B的确认的情况下,A可以连续把窗口内的数据都发送出去,这个数值是20个字节,但在未收到确认之前着这20个字节都必须要暂时保留,以便在超时重传时使用,发送窗口里面的序号表示允许发送的序号,窗口越大发送方就能在得到对方确认前连续发送更多的数据,从而获得更高的传输效率。TCP标准强烈不赞成发送窗口前沿或向后收缩
A发送了11个字节的数据,没有收到任何确认信息,图中的指针P3-P2等于允许发送但尚未发送的字节数,又称可用窗口,p3-p1等于A的发送窗口,又称通知窗口,p2-p1等于已发送但尚未收到确认的字节数,A的发送窗口位置不变。
B的接收窗口中32,33没有按序到达,接收窗口内31-50是允许接收的序号,确认报文段的序号只能是31.
A收到新的确认号34,发送窗口向前滑动,指针P2不变,可用窗口增大为42-53,B的接收窗口37,38,40没有按序到达,只能暂存于接收窗口内.
A继续发送序号42-53,此时P2与P3指针重合,还未收到B的确认,可用窗口减为0,停止发送,纸质收到B的确认,否则启用超时重传,如A收到的确认序号落在窗口内,那么A就可以使窗口继续向前滑动并发送新的数据
发送缓存
缓存空间和序号空间都是有限的,并且都是循环使用的。
发送方的应用进程把字节流写入TCP的发送缓存,发送窗口通常只是发送缓存的一部分,发送缓存和发送窗口的后沿都是重合的,发送应用程序必须控制写入缓存的速率,否则可能造成缓存溢出
对于接收缓存,接收方的应用进程从TCP的接受缓存中读取字节流,收到检测有差错的分组就会被丢弃掉,接受应用程序如若未能来得及读取收到的数据,接收缓存就会被填满,就无法接受新的数据。反之,应用程序能够及时从接收缓存中读取收到的数据,接收窗口就会增大,但不能超过接收缓存的大小。
发送缓存与接收缓存的作用
在发送缓存里,暂存的信息是:
- 发送应用程序传送给发送方TCP准备发送的数据
- TCP已发出但尚未收到确认的数据
在接收缓存中,暂存的信息是:
- 按序到达的但尚未被接受应用程序读取的数据
- 没有按序到达的数据
注意事项:
- A的发送窗口并不总是和B的接收窗口一样大,因为它有一定时间的滞后
- TCP标准没有规定对不按序到达的数据如何处理,通常的处理方法是先临时储存在接收窗口中,等到字节流中所缺少的字节到达后再按序交付给上层的应用进程
- TCP要求接收方必须要有累计确认的功能,这样可以减少传输开销
接收方发送确认
接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息捎带上,但需注意两点:
- 接收方不应过分推迟发送确认,都则会造成发送方不必要的重传,确认推迟时间不能超过0.5s
- 稍待确认实际上并不经常发生,因为大多数应用程序很少在两个方向上发送数据
超时重传时间的选择
TCP每发送一个报文段就对这报文段设置一次计数器,只要计时器时间到且没有收到确认就要重传这一报文段
如何设置超时值
若超时值太小就会造成不必要的重传,若超时值太大丢包恢复的时间又太长,直观上超时值应大于RTT,但RTT是变化的,而且往返时间的方差很大。由于TCP下层是互联网的环境,IP数据报的路由变化很大,因此传输层的往返时间RTT也会很大,所以我们要先对RTT进行估计。
RTT是变化的,需要实际测量某一个报文段的往返时间,也就是样本RTT。由于样本RTT波动很大,所以计算平均值更有意义。
TCP采用了一种自适用的算法,它记录一个报文段所发出的时间以及收到相应确认的时间,这两个时间之差就是报文往返时间RTT。
加权平均往返时间
TCP保留了RTT的加权平均往返时间RTTs,也称平滑的往返时间。第一次测到RTT样本时,RTTs的值就取为所测量到的RTT样本值,以后每测到一个RTT样本就按照公式重新计算一个RTTs。
在公式中α是在0到1之间,若α接近于0则表示RTT值更新较慢,若α接近于1则表示RTT值更新较快,推荐α的数值是八分之一,也就是0.125
超时重传时间RTO
RTO应该略大于上面所得出的加权平均往返时间,RTTd是RDD的偏差的加权平均值。
第一次测量时,RTT值取为到RTT样本值的一半,在以后的测量中使用以下公式计算加权平均的RTTd
这里的β是一个小于1的系数,推荐值是四分之一即0.25
TCP确认的二义性
考虑到可靠传输需要确认机制及RTT的测量,这又引出了TCP确认的二义性
发送方发送了报文段1没有收到确认报文,于是又发送了报文段2,此时收到了确认报文,但是无法辨别是发送给1还是给2的确认,这根本原因是TCP报文段使用了与原报文段相同的序号
Karn算法
当TCP重传一个报文段时,停止测量本次RTT样本,这样得出的加权平均平均往返时间RTTS和超时重传时间RTO比较准确。
但是当出现报文段的时延突然增大了很多的极端情况怎么办呢?根据Karn算法超时重传时间没有办法得到及时的更新,于是对Karn算法进行了修正
修正的Karn算法
报文段每重传一次就把RTO的值增大γ倍,系数γ的典型值是2,当不再发生报文段的重传时才根据报文段的往返时延更新平均往返时延RTT和超时重传时间RTO的数值
选择确认SACK
若收到的报文无差错只是未按照序号到达,中间还缺少一些序号的数组,那么能否设法传送缺少的数据而不传送已经到达接收方的数据呢?答案是可以的。
接收到的字节流序号不连续的情况下,TCP的接收方在接受对方发过来的数据字节流的序号发生了不连续的状态,结果就形成了一些不连续的字节块,前后不连续的每一个字节块都有两个边界,左边界和有边界。
第一个字节块的左边界L1等于1501,但是右边界R1却等于3001,左边界指出字节块第一个字节的序号,但右边界减一才是最后一个字节的序号,第二个字节块的左边界L2等于3501,但是右边界R2却等于4501,接收方收到了前面的字节流不连续的两个字节块,如果这些字节的序号都在接收窗口之内,那么接收方就先收下这些数据,但要把这些信息准确地告诉发送方,使发送方不要再重复发送这些已收到的数据。
RFC 2018的规定
在使用选择确认前,收发双方必须在建立TCP连接时,在TCP首部的选项中加上“允许SACK”的选项。
原首部中的“确认号字段”留用,以后在TCP报文段的首部中都增加了SACK选项,确认收到的不连续的字节块的边界。
首部选项的长度最多只能有40个字节,一个字节块的两个边界就要用到4*2=8个字节,因此在选项字段中最多只能指明4个字节块的边界信息,另外需要两个字节,一个字节指明是SACK选项,一个字节指明此选项占用的字节数。
5.7 TCP的流量控制
通常我们希望数据传输的快一些并且接收方能够来得及接受从而避免丢失,流量控制就是TCP发送端通过调节发送速率不会造成接收端缓存溢出也不会使得网络拥塞。
利用滑动窗口实现流量控制
A向B传送数据,在连接建立时,B告诉A我的接收窗口rwnd=400,A的发送窗口是100,A连续发送两个100的数据都正常确认了,201-300丢失了,此时B确认了201以前的报文并修改了接收窗口为300,A继续分两次发送了301-500,因为201-300丢失所以需要超时重传,此时B的接收窗口已满,B确认了501之前的信息后再次调整接收窗口为100,A再次发送501-600,B确认此次传输接收窗口置0,本次传输中B三次调整接收窗口大小。
零窗口特例下死锁的解决
B向A发送了0窗口的报文段后,B释放了部分接收缓存的空间,并且重新向A发送了rwnd=400的报文段,但此报文丢失而A并不知道,AB双方此时就互相等待对方的信息,陷入了一个死锁的状态。
为了解决这个问题,TCP为每一个连接设置有一个持续计时器,只要TCP连接一方收到了对方的零窗口通知就启动该持续计时器,若持续计时器设置的时间到期就发送一个零窗口的探测报文段,仅携带了一个字节的数据,而对方就在确认这个探测报文段的时候给出了当前的窗口值,若窗口仍然是0,则收到这个报文的一方就重新设置持续计时器,若窗口不是0则死锁的僵局就此打破。
TCP的传输效率
有三种机制控制TCP报文段发送时机
- 第一种机制是TCP维持一个变量,它等于最大报文段长度MSS。只要缓存中存放的1数据达到MSS字节时,就组装成一个TCP报文段发送出去。
- 第二种进制是由发送方的应用进程指明要求发送报文段,即TCP支持的推送操作
- 第三种机制是发送方的一个计时器期限到了,这时就把当前已有的缓存数据装入报文段(但长度不能超过MSS)发送出去
发送方糊涂窗口综合征
发送方TCP每次收到一字节的数据后就发送。
这样,发送一个字节需要形成41字节长的IP数据报。若接收方确认,并且发送方要求回送这一字节,就需传送总长度为162字节共4个报文段,效率很低。
解决办法:使用Nagle算法
Nagle算法
若发送应用进程,把要发送的数据逐个送入到TCP的发送缓存,则发送方就把第一个字节先发送出去,把后面到达的数据都缓存起来;当发送方收到对第一个字节的确认后,再把发送缓存中的所有数据组装成一个报文段发送出去,同时继续对随后到达的数据进行缓存;只有在收到对前一个报文段的确认后,才继续发送下一个报文段;当数据发送较快而网络速率较慢时,用这样的方法可明显减少所用网络带宽;当到达的数据已到达发送窗口一半或报文段最大值时就立即发送一个报文段,这样可以提高网络的吞吐量。
接收方糊涂窗口综合征
当接收方的TCP缓冲区已满,接收方会向发送方发送窗口大小为0的报文。
若此时接收方的应用进程以交互方式每次只读取一个字节,于是接收方又发送窗口大小为一个字节的更新报文,发送方应邀发送一个字节大小的更新报文(IP数据报是41字节长),于是接收窗口又满了,如此循环往复。
解决方法:让接收方等待一段时间,使得或者接收缓存已有足够空间容纳一个最长的报文段,或者等到接收缓存已有一般空闲的空间。只要出现这两种情况之一,接收方就发出确认报文,并向发送方通知“当前的窗口大小”,同时发送方也不要发送太小的报文段。
TCP流量控制小结
TCP接收端:
- 使用显式的窗口通告,告知发送方可用的缓存空间大小。
- 在接收窗口较小时,推迟发送确认。
- 仅当接收窗口显著增加时,通告新的窗口大小。
TCP发送端:
- 使用Nagle算法确定发送时机
- 使用接收窗口限制发送的数据量,已发送未确认的字节数不超过接收窗口的大小
5.8 TCP的拥塞控制
网络拥塞的现象实际上是短时网络中的分组太多,网络带宽不足,解决的措施是减少分组进入网络。
拥塞控制的一般原理
流量控制是限制发送速度,使之不超过接收端的处理能力,也就是接收端控制发送端,而拥塞控制是限制发送速度,使之不超过网络的处理能力,是一个全局性的问题。
网络拥塞产生的后果及原因
网络拥塞会造成:丢包(路由器缓存溢出)、分组延迟增大(链路接近满载)
大量的网络资源用于:重传丢失的分组、不必要地重传延迟过大的分组,转发最终被丢弃的分组
这样会使得网络的负荷很重,流量很大但网络吞吐量却很低,有效流量很少,根本原因是系统对资源的需求总和大于可用的资源
拥塞控制所起的作用
横坐标是输入负载,纵坐标是吞吐量,理想的拥塞控制是在吞吐量达到饱和前曲线以45°斜率的线性增长至饱和水平线,而实际上是随着负载的增加,网络吞吐量的增长率逐渐减小,已进入了轻度拥塞状态,继续增加负载网络吞吐量反而会下降,此时网络拥塞了,负载增加到一定程度,网络吞吐量会降为0,此时为死锁状态,实际拥塞控制曲线基本介乎于理想拥塞控制和无拥塞控制的曲线之间。
实践证明,拥塞控制是很难设计的,因为它是一个动态的问题。
丢包是网络拥塞的征兆,不是引起拥塞的原因
开环控制和闭环控制
开环控制方法就是在设计网络时事先将有关发生拥塞的因素考虑周到,力求网络在工作时不产生拥塞。
闭环控制方法是基于反馈环路的概念,有以下三种措施:
-
监测网络系统,以便监测到拥塞在何时何处发生
-
将拥塞发生的信息传送到可采用行动的地方
-
调整网络系统的运行,以解决出现的问题
监测网络拥塞的指标
- 由于缺少缓存空间而被丢弃的分组的百分比
- 平均队列长度
- 超时重传的分组数
- 平均分组时延
- 分组时延的标准差
上述这些指标的上升都标志着拥塞的增长
方法一监测拥塞发生时通知拥塞发生的分组客观上增加了网络的流量,同样会使网络更加拥塞;方法二在转发分组中增加相应的字段表示网络拥塞状态或周期性地发出探测分组
TCP的拥塞控制方法
TCP采用基于窗口的方法进行拥塞控制,该方法属于闭环控制方法。
TCP发送方维持一个拥塞窗口CWND,拥塞窗口的大小取决于网络的拥塞程度,网络通畅就增大拥塞窗口,提高网络利用率,当网络拥塞时减小拥塞窗口,缓解网络的压力。发送端利用拥塞窗口根据自己感知的网络拥塞程度来调整发送的数据量,所以发送窗口的大小不仅取决于接收方公告的接收窗口,还取决于网络的拥塞状况。
网络拥塞的判断依据
发送方利用丢包时间来感知拥塞,拥塞造成了丢包和分组延迟的增大,这两种情况对于发送端来说都是丢包,丢包事件反映在重传计时器超时或发送端接收到3个重复的确认信号ACK。
发送方通常使用拥塞窗口来限制已发送未确认的数据量,当感知到网络拥塞后,发送方通常是由CWND来随发送方感知的网络拥塞程度进行调整
TCP拥塞控制算法
-
慢开始(slow-start)
算法的思路:在新建连接上指数级增大cwnd,直至检测到丢包,此时会终止慢开始的阶段。它是希望通过迅速增大cwnd至可用的发送速率
原有的规定是先把初始的拥塞窗口的cwnd值设为1至2个发送窗口的最大报文段SMSS,新规则是把初始的拥塞窗口cwnd值设置为不超过2-4个SMSS的数值,防止拥塞窗口cwnd增长过大引起网络拥塞,我们还需要设置一个状态变量慢开始门限ssthresh。
拥塞窗口CWND它的控制方法是在每收到一个对新的报文段的确认后,可以把拥塞窗口增加最多一个SMSS的数值,其中N是原先未被确认的但现在刚确认的报文段的字节数,所以当N小于SMSS的时候,拥塞窗口每次的增加量要小于SMSS。用这样的方法逐渐增大发送方的拥塞窗口,可以使分组注入到网络的速率更加合理。
发送方每收到一个对新报文段的确认(重传不计算在内),就使得cwnd加1,此处的1是一个单位也就是一个报文段,每经过一个RTT将cwnd加倍。
为了防止拥塞窗口cwnd增长过快,还要再设置慢开始门限状态变量ssthresh,它的用法如下:
-
当cwnd<ssthresh时,使用慢开始算法
-
当cwnd>ssthresh时,停止使用慢开始算法而改用拥塞避免算法
-
当cwnd=ssthresh时,既可使用慢开始算法,也可以使用拥塞避免算法
-
拥塞避免(congestion avoidance)
思路:让拥塞窗口cwnd缓慢增大,即每经过一个往返时间RTT就把发送方的拥塞窗口cwnd加1,使拥塞窗口cwnd按线性规律缓慢增长。
在拥塞避免阶段就有“加法增大”的特点,比慢开始算法的拥塞窗口增长速率缓慢得多。
-
在网络拥塞时的处理:
只要发送方判断网络出现拥塞(重传定时器超时):
- ssthresh=max(cwnd/2,2)
- cwnd=1
- 执行慢开始算法
-
慢开始和拥塞避免算法的实现举例
初始cwnd=1,在cwnd<ssthresh的情况下,每经过一个伦茨cwnd就指数增长一次,直到cwnd=ssthresh时,实施拥塞避免算法,cwnd呈线性增长,随着传输轮次的增长每次自增1,当网络拥塞时cwnd变为1,ssthresh降为8,重新一阶段与二阶段,当收到连续三个ACK时,进行快重传算法。
-
快重传(fast retransmit)
快重传算法可以让发送方尽早直到发生了个别报文段的丢失。
快重传算法并非取消重传计时器,而是在某些情况下可更早地重传丢失的报文段。
快重传算法首先要求接收方不要等到自己发送数据时才进行捎带确认,而是要立即发送确认,即使收到了失去的报文段也要立即发出对已收到的报文段的重复确认,发送方只要一连收到三个重复的确认,就知道接收方确实没有收到报文段,因而应当立即进行重传也就是快重传,这样就不会出现超时,发送方也不会误认为网络拥塞。
-
快恢复(fast recovery)
当发送端收到连续三个重复的确认时,由于发送方现在认为网络很可能没有发生拥塞,因此现在不执行慢开始算法,而是执行快恢复算法FR算法:
- 慢开始门限ssthresh=当前拥塞窗口cwnd/2
- 新拥塞窗口cwnd=慢开始门限ssthresh
- 开始执行拥塞避免算法,使拥塞窗口缓慢地线性增大
如图四收到了3个ACK确认,此时执行快恢复算法。
拥塞窗口的调节策略:AIMD
AI指的是加法增大,若无丢包,每经过一个RTT将cwnd增大一个MSS,直到检测到丢包,目的是缓慢增大发送速率。MD指的是乘法减小,发送发检测超时或三个重复确认时,把门限值设为当前拥塞窗口的一半,目的是迅速减小发送速率从,缓解网络压力。
TCP拥塞控制流程图
发送窗口的上限值
发送窗口的上限值应取为接收方窗口rwnd和拥塞窗口cwnd中较小的一个。
5.9 TCP的传输连接管理
传输连接的三个阶段
- 连接建立(握手)
- 数据传送
- 连接释放(放手)
连接建立前的准备
- 要使每一方确知对方的存在
- 要允许双方协商一些参数
- 能够对传输实体的资源进行分配
TCP连接建立采用客户服务器方式,主动发起连接建立的进程叫做客户,被动连接的进程叫做客户