本系列文章为湖南科技大学高军老师的计算机网络微课堂学习笔记,前面的系列文章链接如下:
计算机网络:P1-概述
计算机网络:P2-物理层
计算机网络:P3.1-数据链路层(上)
计算机网络:P3.2-数据链路层(中)
计算机网络:P3.3-数据链路层(下)
计算机网络:P4.1-网络层(上)
计算机网络:P4.2-网络层(中)
计算机网络:P4.3-网络层(下)
一、运输层概述
运输层解决的问题
之前课程所介绍的计算机网络体系结构中的物理层、数据链路层以及网络层,它们共同解决了将主机通过异构网络互联起来所面临的问题,实现了主机到主机的通信。如图所示,局域网1上的主机与局域网2上的主机通过互连的广域网进行通信。网络层的作用范围是主机到主机。
但实际上,在计算机网络中进行通信的真正实体是位于通信两端主机中的进程。例如AP1和AP2是局域网1上这台主机中的与网络通信相关的两个应用进程。AP3和AP4是局域网2上这台主机中的与网络通信相关的两个应用进程。AP是应用进程的英文缩写词。如何为运行在不同主机上的应用进程提供直接的通信服务,是运输层的任务。运输层协议又称为端到端协议。如图所示,运输层的作用范围是应用进程到应用进程,也称为端到端。
从计算机网络体系结构的角度来看运输层
AP1、AP2、AP3、AP4是通信双方应用层中的应用进程,假设AP1与AP4之间进行基于网络的通信,AP2与AP3之间进行基于网络的通信。
在运输层使用不同的端口来对应不同的应用进程,然后通过网络层及其下层来传输应用层报文。接收方的运输层通过不同的端口将收到的应用层报文交付给应用层中相应的应用进程。
需要注意的是,这里的端口并不是指看得见摸得着的物理端口,而是指用来区分不同应用进程的标识符。为了简单起见,在学习和研究运输层时,我们可以简单的认为,运输层直接为应用进程间的逻辑通信提供服务。逻辑通信的意思是,运输层之间的通信好像是沿水平方向传送数据。但事实上,这两个运输层之间并没有水平方向的物理连接,要传送的数据是沿着图中上下多次的曲线方向传送的。
运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),它使应用层看见的就好像是在两个运输层实体之间有一条端到端的逻辑通信信道。根据应用需求的不同,因特网的运输层为应用层提供了两种不同的运输层协议,即面向连接的TCP和无连接的UDP。这两种协议就是本章要讨论的主要内容。
小测验
1、运输层为( )之间提供逻辑通信服务。
A. 主机
B. 进程
C. 路由器
D. 操作系统
答案:B
2、在TCP/IP体系结构中,运输层的主要作用是在互联网络的源主机和目的主机对等实体之间建立用于会话的( )
A. 点到点连接
B. 操作连接
C. 端到端连接
D. 控制连接
答案:C
二、运输层端口号、复用与分用的概念
运输层端口号
背景: 运输层的任务是直接为应用进程间的逻辑通信提供服务。运输层使用端口号来区分不同的应用进程。我们知道,运行在计算机上的进程是使用进程标识符PID来标志的。然而,因特网上的计算机并不是使用统一的操作系统,不同操作系统(例如Windows、Linux、Mac OS等)又使用不同格式的进程标识符。为了使运行不同操作系统的计算机的应用进程之间能够进行网络通信,就必须使用统一的方法对TCP/IP体系的应用进程进行标识。
运输层端口号分类
TCP/IP体系的运输层使用端口号来区分应用层的不同应用进程,端口号使用16比特来标识,取值范围是0~65535,分为以下三种:
①熟知端口号。取值范围是0~1023,因特网数字分配机构IANA把这些端口号指派给了TCP/IP体系中最重要的一些应用协议。例如,FTP协议使用21和22号端口,HTTP协议使用80号端口,DNS使用53号端口。
②登记端口号。取值范围是1024~49151,为没有熟知端口号的应用程序所使用。使用这类端口号必须在IANA按照规定的手续登记,以防止重复。例如,微软远程桌面应用程序使用的端口号是3389。
③短暂端口号。取值范围是49152~65535,留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用。
注意: 端口号只具有本地意义,即端口号只是为了标识本计算机应用层中的各进程。在因特网中,不同计算机中的相同端口号是没有联系的。
发送方的复用和接收方的分用
发送方的复用
如图所示,这是收发双方的应用进程。
①发送方的某些应用进程所发送的不同应用报文在运输层使用UDP协议进行封装,这称为UDP复用。
②而另一些应用进程所发送的不同应用报文在运输层使用TCP协议进行封装,这称为TCP复用。
③运输层使用端口号来区分不同的应用进程。不管是使用运输层的UDP协议封装成的UDP用户数据报,还是使用TCP协议封装成的TCP报文段,在网络层都需要使用IP协议封装成IP数据报,这称为为IP复用。
④IP数据报首部中协议字段的值用来表明IP数据报的数据载荷部分封装的是何种协议数据单元。取值为6,表示封装的是TCP报文段。取值为17,表示封装的是UDP用户数据报。
接收方的分用
①接收方的网络层收到IP数据报后进行IP分用。
②若IP数据报首部中协议字段的值为17,则把IP数据报的数据载荷部分所封装的UDP用户数据报上交运输层的UDP。若协议字段的值为6,则把IP数据报的数据载荷部分所封装的TCP报文段上交运输层的TCP。
③运输层对UDP用户数据报进行UDP分用,对TCP报文段进行TCP分用,也就是根据端口号将他们交付给上层相应的应用进程。
应用层常用协议所使用的运输层熟知端口号
下面这些是TCP/IP体系的应用层常用协议,左边这些协议在运输层使用UDP协议,右边这些协议在运输层使用TCP协议,这是他们各自使用的运输层熟知端口号。不管在运输层使用UDP还是TCP协议,在网络层都需要使用IP协议。IP数据报首部中协议字段的值表明了IP数据报数据载荷部分封装的是何种协议数据单元。
举例说明运输层端口号的作用:
如图所示,用户PC、DNS服务器、Web服务器通过交换机进行互联,它们处于同一个以太网中。假设这是Web服务器的域名,DNS服务器中记录有该域名所对应的IP地址。我们在用户PC中使用网页浏览器来访问Web服务器的内容,在网页浏览器的地址栏中输入Web服务器的域名。
①用户PC中的DNS客户端进程会发送一个DNS查询请求报文,其内容为"域名www.protest.com所对应的IP地址是什么?“。DNS查询请求报文需要使用运输层的UDP协议封装成UDP用户数据报,其首部中的源端口字段值在短暂端口号49151到65535中挑选一个未被占用的,用来表示DNS客户端进程,例如49152。目的端口字段的值设置为53,这是DNS服务器端进程所使用的熟知端口号。
②之后将UDP用户数据报封装在IP数据报中,通过以太网发送给DNS服务器。DNS服务器端收到该数据报后,从中解封出UDP用户数据报。UDP首部中的目的端口号为53,这表明应将该UDP用户数据报的数据载荷部分,也就是DNS查询请求报文交付给本服务器中的DNS服务器端进程。DNS服务器端进程解析DNS查询请求报文的内容,然后按其要求查找对应的IP地址。
③之后,会给用户PC发送DNS的响应报文,其内容为"域名www.parttest.com所对应的IP地址是192.168.0.3”。DNS响应报文需要使用运输层的UDP协议封装成UDP用户数据报,其首部中的源端口字段的值设置为熟知端口号53,表明这是DNS服务器端进程所发送的UDP用户数据报。目的端口字段的值设置为49152,这是之前用户PC中发送DNS查询请求报文的DNS客户端进程所使用的短暂端口号。
④之后将UDP用户数据报封装在IP数据报中通过以太网发送给用户PC。用户PC收到该数据报后,从中解封出UDP用户数据报。UDP首部中的目的端口号为49152,这表明应将该UDP用户数据报的数据载荷部分,也就是DNS响应报文交付给用户PC中的DNS客户端进程。DNS客户端进程解析DNS响应报文的内容,就可知道自己之前所请求的外部服务器的域名所对应的IP地址为192.168.0.3。
⑤现在,用户PC中的HTTP客户端进程可以向Web服务器发送HTTP请求报文了,其内容为"首页内容是什么?"。HTTP请求报文需要使用运输层的TCP协议封装成TCP报文段,其首部中的源端口字段的值在短暂端口号49151到65535中挑选一个未被占用的,用来表示HTTP客户端进程,例如仍然使用之前用过的49152。目的端口字段的值设置为80,这是HTTP服务器端进程所使用的熟知端口号。之后将TCP报文段封装在IP数据报中,通过以太网发送给Web服务器。
⑥Web服务器收到该数据报后,从中解封出TCP报文段。TCP首部中的目的端口号为80,这表明应该将该TCP报文段的数据载荷部分,也就是HTTP请求报文交付给本服务器中的HTTP服务器端进程。HTTP服务器端进程解析HTTP请求报文的内容,然后按其要求查找首页内容。之后会给用户PC发送HTTP响应报文,其内容是HTTP客户端所请求的首页内容。HTTP响应报文需要使用运输层的TCP协议封装成TCP报文段,其首部中的源端口号字段的值设置为熟知端口号80,表明这是HTTP服务器端进程所发送的TCP报文段。目的端口字段的值设置为49152,这是之前用户PC中发送HTTP请求报文的HTTP客户端进程所使用的短暂端口号。之后,将TCP报文段封装在IP数据报中,通过以太网发送给用户PC。
⑦用户PC收到该数据报后,从中解封出TCP报文段。TCP首部中的目的端口号为49152,这表明应该将该TCP报文段的数据载荷部分,也就是HTTP响应报文交付给用户PC中的HTTP客户端进程。HTTP客户端进程解析HTTP响应报文的内容,并在网页浏览器中进行显示。这样我们就可以在网页浏览器中看到Web服务器所提供的首页内容了。
小测验
1、在TCP/IP中,采用( )来区分不同的应用进程。
A. 端口号
B. IP地址
C. 协议类型
D. MAC地址
答案:A
2、在TCP/IP网络中,为各种熟知应用保留的端口号范围是
A. 1~255
B. 0~1023
C. 1~1024
D. 1~65535
答案:B
3、在TCP/IP中,运输层端口号的范围是
A. 1~255
B. 0~1023
C. 1~1024
D. 0~65535
答案:D
三、UDP和TCP的对比
前言
UDP和TCP是TCP/IP体系结构运输层中的两个重要协议。如图所示,这是我们之前课程中介绍过的TCP/IP体系结构。在使用TCP/IP体系结构的网络通信中,这两个协议的使用频率仅次于网际层的IP协议。TCP/IP体系结构应用层中的某些协议需要使用运输层的TCP提供的服务,而另一些协议需要使用运输层的UDP提供的服务。
UDP(User Datagram Protocol)是用户数据报协议的英文缩写词。
TCP(Transmission Control Protocol)是传输控制协议的英文缩写词。
接下来,我们将从几个方面对这两个协议进行比较
传输前处理
如图所示,这是因特网上两台主机,纵坐标为时间。
①在运输层使用UDP协议进行通信时,通信双方可以随时发送数据。
②使用TCP协议的通信双方在进行数据传输之前,必须使用三报文握手来建立TCP连接。TCP连接建立成功后才能进行数据传输。数据传输结束后,必须使用四报文挥手来释放TCP连接。三报文握手和四报文挥手属于TCP的连接管理,其过程比较复杂,我们将在后续课程中专门介绍。
需要注意的是,这里所谓的连接是指逻辑连接关系,而不是物理连接。综上所述,UDP是无连接的,而TCP是面向连接的。
通信方式
①这是某个局域网上的使用UDP协议进行通信的4台主机。其中任何一台主机都可向其它三台主机发送广播
也可以向某个多播组发送多播
还可以向某台主机发送单播。
也就是说,UDP支持单播、多播以及广播。换句话说,UDP支持一对一、一对多、一对全的通信。
②使用TCP协议的通信双方在进行数据传输之前必须使用三报文握手来建立TCP连接。TCP连接建立成功后,通信双方之间就好像有一条可靠的通信信道。通信双方使用这条基于TCP连接的可靠信道进行通信。很显然,TCP仅支持单播,也就是一对一的通信。
对应用报文的处理
对于UDP协议,发送方的应用进程将应用层报文交付给运输层的UDP。UDP直接给应用层报文添加一个UDP首部,使之成为UDP用户数据报,然后进行发送。需要说明的是,为了简单起见,我们忽略运输层下面的各层处理。接收方的UDP,收到该UDP用户数据报后,去掉UDP首部,将应用层报文交付给应用进程。也就是说,UDP对应进程交下来的报文既不合并也不拆分,而是保留这些报文的边界。换句话说,UDP是面向应用报文的。
②发送方的TCP把应用进程交付下来的数据块仅仅看作是一连串的无结构的字节流。TCP并不知道这些带传送的字节流的含义,仅将他们编号并存储在自己的发送缓存中。
TCP根据发送策略,从发送缓存中提取一定数量的字节,构建TCP报文段并发送。
接收方的TCP一方面从所接收到的TCP报文段中取出数据载荷部分并存储在接收缓存中。一方面,将接收缓存中的一些字节交付给应用进程。
TCP不保证接收方应用进程所收到的数据块与发送方应用进程所发出的数据块具有对应大小的关系。例如,发送方应用进程交给发送方的TCP共十个数据块儿,但接收方的TCP可能只用了4个数据块儿就把收到的字节流交付给了上层的应用进程。但接收方应用进程收到的字节流必须和发送方应用进程发出的字节流完全一样。当然,接收方的应用进程必须有能力识别收到的字节流,把它还原成有意义的应用层数据。也就是说,TCP是面向字节流的,这正是TCP实现可靠传输、流量控制、拥塞控制的基础。需要说明的是,为了突出示意图的要点,我们只画出了一个方向的数据流。在实际网络中,基于TCP连接的两端可以同时进行TCP报文段的发送和接收,也就是全双工通信。另外,图中TCP报文段的数据部分只包含了几个字节。实际中,一个TCP报文段包含上千个字节是很常见的。
服务可靠性
在之前的课程中,我们曾介绍过TCP/IP体系结构的网际层向其上层提供的是无连接、不可靠的传输服务。
②当运输层使用UDP协议时,向其上层提供的也是无连接、不可靠的传输服务。
----发送方给接收方发送UDP用户数据报,若传输过程中用户数据报受到干扰而产生误码,接收方UDP可以通过该数据报首部中的校验和字段的值检查出产生误码的情况。但仅仅丢弃该数据报,其他什么也不做。
----发送方给接收方发送UDP用户数据报,如果该数据报被因特网中的某个路由器丢弃了,发送方UDP不做任何处理,因为UDP向上层提供的是无连接、不可靠的传输服务。
因此,对于UDP用户数据报出现的误码和丢失等问题,UDP并不关心。基于UDP的这个特点,UDP适用于实时应用,例如IP电话、视频会议等。
②再来看使用TCP协议的情况。尽管网层中的IP协议向上层提供的是无连接、不可靠的传输服务。也就是说,IP数据报可能在传输过程中出现丢失或误码,但只要运输层使用TCP协议,就可向其上层提供面向连接的可靠传输服务。我们可将其想象成使用TCP协议的收发双方基于TCP连接的可靠信号进行数据传输,不会出现误码、丢失、乱序以及重复等传输差错。TCP适用于要求可靠传输的应用,例如文件传输。
报文首部
①一个UDP用户数据报由首部和数据载荷两部分构成,其首部格式如图所示。仅有4个字段,每个字段长度为2个字节。由于UDP不提供可靠传输服务,它仅仅在网际层的基础上添加了用于区分应用进程的端口。因此,它的首部非常简单,仅有8个字节。
②一个TCP报文段由首部和数据载荷两部分构成,其首部格式如图所示。这比UDP用户数据报的首部复杂得多,其最小长度为20字节,最大长度为60字节。这是因为TCP要实现可靠传输、流量控制、拥塞控制等服务。其首部自然会比较复杂,首部中的字段比较多,首部长度也比较长。
总结
两种协议对比如下
小测验
1、以下字段包含在TCP首部中而不包含在UDP首部中的是
A. 目标端口号
B. 序号
C. 源端口号
D. 校验和
答案:B
2、若接收端收到有差错的UDP用户数据报,则会
A. 将其丢弃
B. 请求重传
C. 纠错
D. 忽略差错
答案:A
3、UDP用户数据报比IP数据报多提供了
A. 流量控制功能
B. 拥塞控制功能
C. 端口功能
D. 路由转发功能
答案:C
4、下列不属于TCP特点的是
A. 面向字节流
B. 全双工
C. 可靠
D. 支持广播
答案:D
四、TCP的流量控制
TCP的流量控制
①一般来说,我们总是希望数据传输得更快一些。但如果发送方把数据发送的过快,接收方就可能来不及接收,这就会造成数据的丢失。
②所谓流量控制,就是让发送方的发送速率不要太快,要让接收方来得及接收。
③利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。
例子:
假设主机A和B是因特网上的两台主机,它们之间已经建立了TCP连接。A给B发送数据,B对A进行流量控制。这是主机A中待发送数据的字节序号。假设主机A发送的每个TCP报文段可携带100字节数据。因此,图中每个小格子表示100个字节数据的序号。在主机A和B建立TCP连接时,B告诉A,我的接收窗口为400。因此主机A将自己的发送窗口也设置为400。这意味着主机A在未收到主机B发来的确认时,可将序号落入发送窗口中的全部数据发送出去。
流量控制
接下来我们以上面那个例子说明主机B对A的流量控制。
主机A将发送窗口内序号1到100的数据封装成一个TCP报文段发送出去,发送窗口内还有300字节可以发送。这里的seq是TCP报文段首部中的序号字段,取值1表示TCP报文段数据载荷的第1个字节的序号是1。这里的DATA表示这是TCP数据报文段。
主机A将发送窗口内序号101到200的数据封装成一个TCP报文段发送出去,发送窗口内还有200字节可以发送。
主机A将发送窗口内序号201到300的数据封装成一个TCP报文段发送出去。但该报文段在传输过程中丢失了。主机A发送窗口内还有100字节可以发送。
主机B对主机所发送的201号以前的数据进行累计确认,并在该累计确认中将窗口字段的值调整为300,也就是对主机A进行流量控制。这里的大写ACK是TCP报文段首部中的标志位,取值1表示这是一个TCP确认报文段。小写ack是TCP报文段首部中的确认号字段,取值201表示序号201之前的数据已全部正确接收,现在希望收到序号201及其后续数据。rwnd是TCP报文段首部中的窗口字段,取值300表示自己的接收窗口大小为300。这是主机B对主机1的第1次流量控制。
主机A收到该累计确认后,将发送窗口向前滑动,使已发送并收到确认的这些数据的序号移出发送窗口。由于主机B在该累计确认中将自己的接收窗口调整为了300,因此,主机A相应地将自己的发送窗口调整为300。
目前主机A发送窗口内的序号为201到500,也就是主机A还可以发送这300字节。其中201到300号字节是已发送的数据,若重传计时器超时,它们会被重传。301~400号字节以及401~500号字节还未被发送,可被分别封装在一个TCP报文段中发送。主机A现在可将发送缓存中序号1~200个字节数据全部删除了,因为已经收到了主机B对它们的累计确认。主机A将发送窗口内序号301到400的数据封装成一个TCP报文段发送出去,发送窗口内还有100字节可以发送。
主机A将发送窗口内序号401到500的数据封装成一个TCP报文段发送出去。至此,序号落在发送窗口内的数据已经全部发送出去了,不能再发送新数据了。
现在发送窗口内序号201到300这100个字节数据的重传计时器超时了。主机A将它们重新封装成一个TCP报文段发送出去,暂时不能发送其他数据。
主机B收到该重传的TCP报文段后,对主机A所发送的501号以前的数据进行累计确认,并在该累计确认中将窗口字段的值调整为100。这是主机B对主机A进行的第2次流量控制。
主机A收到该累计确认后,将发送窗口向前滑动,使已发送并收到确认的这些数据的序号移出发送窗口。由于主机B在该累计确认中将自己的接收窗口调整为了100,因此,主机A相应地将自己的发送窗口调整为100。目前主机A发送窗口内的序号为501到600,也就是主机A还可以发送这100字节。主机A现在可将发送缓存中序号201到500的字节数据全部删除了,因为已经收到了主机B对他们的累计确认。
主机A将发送窗口内序号501到600的数据封装成一个TCP报文段发送出去。至此,序号落在发送窗口内的数据已经全部发送出去了,不能再发送新数据了。
主机B对主机A所发送的601号以前的数据进行累计确认。在该累计确认中,将窗口字段的值调整为0。这是主机B对主机A进行的第3次流量控制。
主机A收到该累计确认后,将发送窗口向前滑动,使已发送并收到确认的这些数据的序号移出发送窗口。
由于主机B在该累计确认中将自己的接收窗口调整为了0。因此,主机A相应地将自己的发送窗口调整为0。目前主机A不能再发送一般的TCP报文段了。主机A现在可将发送缓存中序号501到600的字节数据全部删除了,因为已经收到了主机B对他们的累计确认。
一些假设情况
①假设主机B向主机A发送了零窗口的报文段后不久,主机B的接收缓存又有了一些存储空间。于是主机B向主机A发送了接收窗口等于300的报文段。然而,这个报文段在传输过程中丢失了,主机A一直等待主机B发送的非零窗口的通知,而主机B也一直等待主机A发送的数据。如果不采取措施,这种互相等待而形成的死锁局面将一直持续下去。
解决方案: 为了解决这个问题,TCP为每一个连接设有一个持续计时器。
----只要TCP连接的一方收到对方的零窗口通知,就启动持续计时器。
----若持续计时器超时,就发送一个零窗口探测报文,仅携带一字节的数据。
----而对方在确认这个探测报文段时,给出自己现在的接收窗口值。如果接收窗口仍然是0,那么收到这个报文段的一方就重新启动持续计时器。如果接入窗口不是0,那么死锁的局面就可以被打破了。
在本例中,主机A收到零窗口通知时,就启动一个持续计时器。当持续计时器超时,主机A立刻发送一个仅携带1字节数据的零窗口探测报文段。假设主机B此时的接收窗口又为0了。主机B就在确认这个零窗口探测报文段时,给出自己现在的接收窗口值为零。主机A再次收到零窗口通知,就再次启动一个持续计时器。当持续计时器超时,主机A立刻发送一个零窗口探测报文段。
假设主机B此时的接收缓存又有了一些存储空间,于是将自己的接收窗口调整为300。主机B就在确认这个零窗口探测报文段时,给出自己现在的接收窗口值为300。这样就打破了死锁的局面。
疑问: 主机A所发送的零窗口探测报文段到达主机B时,如果主机B此时的接收窗口仍然为0,那么主机B根本就无法接受该报文段,又怎么会针对该报文段给主机A发回确认呢?
回答: 实际上,TCP规定即使接收窗口为0,也必须接受零窗口探测报文段、确认报文段、携带有紧急数据的报文段。
思考: 如果零窗口探测报文段丢失了,会出现怎样的问题呢?还能否打破死锁的局面呢?
回答: 可以打破死锁局面。因为零窗口探测报文段也有重传计时器,当重传计时器超时后,零窗口探测报文段会被重传。
例题
【2010年题39】主机甲和主机乙之间建立了一个TCP连接,TCP最大段长度为1000字节。若主机甲的当前拥塞窗口为4000字节,在主机甲向主机乙连续发送两个最大段后,成功收到主机乙发送的第一个段的确认段,确认段中通告的接收窗口大小为2000字节,则此时主机甲还可以向主机乙发送的最大字节数是 (A)
A. 1000
B. 2000
C. 3000
D. 4000
前提条件: 由于该题涉及到了我们还未学习的拥塞控制的内容,因此我们需要先做一些说明,然后再请同学们来完成。TCP发送方的发送窗口实际上是在自身的拥塞窗口和TCP接收方的接收窗口中取小者。而在我们本节课的举例中,为了简单起见,我们忽略了拥塞控制,也就是认为TCP发送方的发送窗口等于接收方的接收窗口。本题未给出TCP发送方的发送窗口的初始值,则我们取拥塞窗口值作为发送窗口值。
解析: 下图是主机甲中待发送数据的序号。根据题意可知,主机甲的发送窗口为4000字节。主机甲向主机乙连续发送两个最大段,共2000字节,也就是将发送窗口内序号0到1999的字节数据发送出去。
主机乙给主机甲发送针对第一个段的确认,并在该确认中给出自己的接收窗口大小为2000字节。
主机甲收到该确认后,将发送窗口向前滑动,使已发送并收到确认的第一个段的序号移出发送窗口。
由于主机已在确认中给出的自己的接收窗口大小为2000字节。因此,主机甲相应地将自己的发送窗口调整为2000字节。
很显然,主机甲还可以向主机乙发送2000到2999号字节数据,共1000个字节。
小测验
1、A和B建立了TCP连接,当A收到确认号为100的TCP确认报文段时,表示
A. 已收到99号TCP报文段
B. 已收到100号TCP报文段
C. 已收到数据载荷部分最后一字节序号为99的TCP报文段
D. 已收到数据载荷部分最后一字节序号为100的TCP报文段
答案:C
2、在TCP协议中,发送方的窗口大小取决于
A. 仅接收方允许的窗口
B. 接收方允许的窗口和发送方允许的窗口
C. 接收方允许的窗口和拥塞窗口
D. 发送方允许的窗口和拥塞窗口
答案:C
3、主机甲和主机乙之间建立了一个TCP连接,TCP最大段长度为1000字节,若主机甲当前发送窗口为6000字节,不考虑拥塞窗口,在主机甲向主机乙连续发送三个最大段后,成功收到主机乙发送的第一个段的确认段,确认段中通告的接收窗口大小为4000字节,则此时主机甲还可以向主机乙发送的最大字节数是
A. 1000
B. 2000
C. 3000
D. 4000
答案:B
五、TCP的拥塞控制
拥塞控制的基本概
在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏,这种情况就叫做拥塞(congestion)。在计算机网络中的链路容量(即带宽)、交换节点中的缓存和处理机等都是网络的资源。若出现拥塞而不进行控制,整个网络的吞吐量将随输入负载的增大而下降。
拥塞控制的作用
下图中,横坐标是输入负载,代表单位时间内输入给网络的分组数量。纵坐标是吞吐量,代表单位时间内从网络输出的分组数量。具有理想拥塞控制的网络,在吞吐量达到饱和之前,网络吞吐量应等于所输入的负载,故吞吐量曲线是45度的斜线。但当输入负载超过某一限度时,由于网络资源受限,吞吐量就不再增长,而保持水平线,也就是吞吐量达到饱和。这就表明输入的负载中有一部分损失掉了。例如,输入到网络中的某些分组被某个节点丢弃了。虽然如此,在这种理想的拥塞控制作用下,网络的吞吐量仍然维持在其所能达到的最大值。
然而,实际的网络情况就很不同了。随着输入负载的增大,网络吞吐量的增长率逐渐减小,也就是在网络吞吐量还未达到饱和时就已经有一部分的输入分组被丢弃了。当网络的吞吐量明显地小于理想的吞吐量时,网络就进入了轻度拥塞的状态。更值得注意的是,当输入负载到达某一数值时,网络的吞吐量反而随输入负载的增大而减小,这时网络就进入了拥塞状态。当输入负载继续增大到某一数值时,网络的吞吐量就减小为0,此时网络就无法工作了,这就是所谓的死锁。
因此,进行拥塞控制是非常有必要的,实际的拥塞控制曲线应该尽量接近理想的拥塞控制曲线。
TCP的四种拥塞控制算法
TCP的四种拥塞控制算法分别是慢开始、拥塞避免、快重传、快恢复。我们来举例说明TCP这四种拥塞算法的基本原理。为了集中精力讨论拥塞控制,我们假定如下条件:
①数据是单方向传送的,而另一个方向只传送确认。
②接收方总是有足够大的缓存空间,因而发送方发送窗口的大小仅由网络拥塞程度来决定。
③以TCP最大报文段的个数为讨论问题的单位,而不是以字节为单位。
假设下图是TCP的发送方和接收方。发送方给接收方发送TCP数据报文段,接收方收到后给发送方发送TCP确认报文段。
①发送方要维护一个叫做拥塞窗口cwnd
的状态变量,其值取决于网络的拥塞程度,并且动态变化。
----拥塞窗口的维护原则是:只要网络没有拥塞,拥塞窗口就再增大一些。但只要网络出现拥塞,拥塞窗口就减小一些。
----判断出现网络拥塞的依据是:没有按时收到应当到达的确认报文段,也就是发生了超时重传。
②发送方将拥塞窗口作为发送窗口swnd
,也就是swnd=cwnd
。
③发送方还需要维护一个叫做慢开始门限ssthresh
的状态变量。
----当拥塞窗口小于慢开始门限时,使用慢开始算法。
----当拥塞窗口大于慢开始门限时,停止使用慢开始算法,而改用拥塞避免算法。
----当拥塞窗口等于慢开始门限时,既可以使用慢开始算法,也可以使用拥塞避免算法。
慢开始
为了更清楚地显示出拥塞控制过程,我们还可以绘制这样一幅拥塞窗口随传输轮次变化的图。横坐标为传输轮次,传输轮次是指发送方给接收方发送数据报文段后,接收方给发送方发回相应的确认报文段。一个传输轮次所经历的时间其实就是往返时间。请注意,往返时间并非是恒定的数值,使用传输轮次是为了强调把拥塞窗口所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个报文段的确认。纵坐标是拥塞窗口,它会随网络拥塞程度以及所使用的拥塞控制算法动态变化。
在TCP双方建立逻辑连接关系时,拥塞窗口的值被设置为1,我们在图上标出传输轮次0时的拥塞窗口值为1。另外,还需设置慢开始门限的初始值,本例采用16,我们也将它在图中标出。在执行慢开始算法时,发送方每收到一个对新报文段的确认时,就把拥塞窗口值加1,然后开始下一轮的传输。当拥塞窗口值增长到慢开始门限值时,就改为执行拥塞避免算法。由于发送方当前的拥塞窗口值是1,而发送窗口值等于拥塞窗口值。因此,发送方当前只能发送1个TCP数据报文段。换句话说,拥塞窗口值是几就能发送几个数据报文段。如图所示,发送方发送0号数据报文段。
接收方收到后,给发送方发回对0号报文段的确认报文段。发送方收到该确认报文段后,将拥塞窗口值加1增大到2,我们在图中标出该值。
这意味着发送方现在可以发送1到2号共两个数据报文段。
接收方收到后,给发送方发回对1到2号报文段的确认报文段。发送方收到后,将拥塞窗口值加2增大到4,我们在图中标出该值。
发送方现在可以发送3到6号共4个数据报文段。
接收方收到后,给发送方发回对3到6号报文段的确认报文段。发送方收到后,将拥塞窗口值加4增大到8,我们在图中标出该值。
发送方现在可以发送7到14号共8个数据报文段。
接收方收到后,给发送方发回对7到14号报文段的确认报文段。发送方收到后,将拥塞窗口值加8增大到16,我们在图中标出该值。
发送方当前的拥塞窗口值已经增大到了慢开始门限值,之后我们要改用拥塞避免算法,也就是每个传输轮次结束后,拥塞窗口值只能线性加1,而不像慢开始算法那样,每个传输轮次结束后,拥塞窗口值按指数规律增长。
拥塞避免
发送方现在可以发送15到30号共16个数据报文段。
接收方收到后,给发送方发回对15到30号报文段的确认报文段。发送方收到后,将拥塞窗口值加1增大到17,我们在图中标出该值。
发送方现在可以发送31到47号共17个数据报文段。接收方收到后,给发送方发回对31到47号报文段的确认报文段。发送方收到后,将拥塞窗口值加1增大到18,我们在图中标出该值。
随着传输轮次的增加,拥塞窗口值每轮次都线性加1。例如当前拥塞窗口值增加到了24,发送方现在可以发送171到194号共24个数据报文段。假设这24个数据报文段在传输过程中丢失了几个。
这必然会造成发送方对这些丢失报文段的超时重传。发送方以此判断,网络很可能出现了拥塞,需要进行以下工作:
①将慢开始门限值更新为发生拥塞时拥塞窗口值的一半。网络发生拥塞时的拥塞窗口值是24,因此更新慢开始门限值为该值的一半,即12
②将拥塞窗口值减小为1,并重新开始执行慢开始算法。
当慢开始执行到拥塞窗口值增大到新的慢开始门限值时,就要停止使用慢开始算法,转而执行拥塞避免算法,如图所示。
总结: 通过本例可以看出:
①TCP发送方一开始使用慢开始算法,让拥塞窗口值从1开始按指数规律增大。
②当拥塞窗口值增大到慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。
③当发生超时重传时,就判断网络很可能出现了拥塞,采取相应的措施。一方面将慢开始门限值更新为发生拥塞时拥塞窗口值的一半,另一方面将拥塞窗口值减小为1,并重新开始执行慢开始算法。
④拥塞窗口值又从1开始按指数规律增大,当增大到了新的慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加的规律增大。
注: 需要注意的是,慢开始是指一开始向网络注入的报文段少,而并不是指拥塞窗口值增长速度慢。拥塞避免也并非指完全能够避免拥塞,而是旨在拥塞避免阶段将拥塞窗口值控制为按线性规律增长,使网络比较不容易出现拥塞。
快重传
背景: 慢开始和拥塞避免是1988年就提出的TCP拥塞控制算法,也就是TCP Tahoe版本。1990年又增加了两个新的拥塞控制算法,以便改进TCP的性能,就是快重传和快恢复,被称为TCP的Reno版本。有时个别报文段会在网络中丢失,但实际上网络并未发生拥塞。这将导致发送方超时重传,并未认为网络发生了拥塞。例如,在之前的例子中,当拥塞窗口值增大到24时,发生了超时重传。而网络此时并没有发生拥塞,但是发送方却误认为网络发生了拥塞。于是,发送方把拥塞窗口值减小为1,并错误地启动慢开始算法,因而降低了传输效率。
快重传算法
采用快重传算法,可以让发送方尽早知道发生了个别报文段丢失。所谓快重传,就是使发送方尽快进行重传,而不是等超时重传计时器超时再重传。
----这就要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认。
----即使收到了失序的报文段,也要立即发送对已收到的报文段的重复确认。
----发送方一旦收到3个连续的重复确认,就将相应的报文段立即重传,而不是等该报文段的重传计时器超时再重传。
例子: 发送方发送1号数据报文段,接收方收到后给发送方发回对1号报文段的确认。
在该确认报文段到达发送方之前,发送方还可以将发送窗口内的2号数据报文段发送出去。接收方收到后,给发送方发回对2号报文段的确认。
在该确认报文段到达发送方之前,发送方还可以将发送窗口内的3号数据报文段发送出去。但该报文段丢失了,接收方自然不会给发送方发回针对该报文段的确认。
发送方还可以将发送窗口内的4号数据报文段发送出去。接收方收到后发现这不是按序到达的报文段,因此给发送方发回针对2号报文段的重复确认,表明我现在希望收到的是3号报文段,但是我没有收到3号报文段,而是收到了未按序到达的报文段。
发送方还可以将发送窗口内的5号数据报文段发送出去。接收方收到后发现这不是按序到达的报文段,因此给发送方发回针对2号报文段的重复确认。
发送方还可以将发送窗口内的6号数据报文段发送出去。接收方收到后发现,这不是按序到的报文段,因此给发送方发回针对2号报文段的重复确认。
至此,发送方会收到3个连续的对2号报文段的重复确认,就立即重传3号报文段。
接收方收到后,给发送方发回针对6号报文段的确认,表明序号到6为止的报文段都正确接收了。这样就不会造成对3号报文段的超时重传,而是提早进行了重传。对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞而错误地降低拥塞窗口值为最小值1。使用快重传可以使整个网络的吞吐量提高约20%。
快恢复
发送方一旦收到三个重复确认,就知道现在只是丢失了个别的报文段,于是不启动慢开始算法,而是执行快恢复算法。
①发送方将慢开始门限值和拥塞窗口值调整为当前窗口值的一半,开始执行拥塞避免算法。
②也有的快恢复实现是把快恢复开始时的拥塞窗口值再增大一些,也就是等于新的慢开始门限值加3。这样做的理由是:
----既然发送方收到3个重复的确认,就表明有3个数据报文段已经离开了网络。
----这3个报文段不再消耗网络资源,而是停留在接收方的接收缓存中。
----可见现在网络中不是堆积了报文段,而是减少了3个报文段。因此,可以适当把拥塞窗口值扩大一些。
总结:
我们来看看TCP拥塞窗口值在拥塞控制时的变化情况举例,里面包含了TCP拥塞控制的四种算法。
①TCP发送方一开始使用慢开始算法,让拥塞窗口值从1开始按指数规律增大。
②当增大到慢开始门限初始值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。
③当发生超时重传时,就判断网络可能出现了拥塞,采取相应的措施。一方面,将慢开始门限值更新为发生拥塞时拥塞窗口值的一半。另一方面,将拥塞窗口值减小为1,并重新开始执行慢开始算法。
④拥塞窗口值又从1开始按指数规律增大,当增大到了新的慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法,⑤让拥塞窗口值按线性加1的规律增大。
⑥当发送方收到三个重复的确认时,就进行快重传和快恢复。也就是更新慢开始门限值为当前拥塞窗口值的一半,并将拥塞窗口值也取为新的慢开始门限值,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。
例题
【2009年题39】一个TCP连接总是以1KB的最大段长发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为16KB时发生了超时,如果接下来的4个RTT(往返时间)内的TCP段的传输都是成功的,那么当第4个RTT时间内发送的所有TCP段都得到肯定应答时,拥塞窗口大小是 (C)
A. 7KB
B. 8KB
C. 9KB
D. 16KB
解析: 根据题意,我们可以画出发送方拥塞窗口值随传输轮次的变化图。
----最开始是慢开始部分。
----当拥塞窗口值增大到慢开始门限的初始值时,停止使用慢开始算法,转而执行拥塞避免算法。根据题意,当拥塞窗口值增大到16K字节时,发生了超时重传。于是将慢开始门限值更新为当前拥塞窗口值的一半,并将拥塞窗口值减小为1K字节,并重新开始执行慢开始算法。
----当拥塞窗口值增大到新的慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法。
可以看到该处就是题目所问的在超时后的四个往返时间后,也就是在超时后的四个传输轮次结束后,拥塞窗口值增长到9K字节。需要说明的是,题目并未给出慢开始门限值的初始值。因此,这部分传输轮次只是示意,目的是为了让大家能够更好的理解。
小测验
1、以下关于TCP窗口与拥塞控制概念的描述中,错误的是
A. 接收窗口通过TCP首部中的窗口字段通知数据的发送方
B. 发送窗口确定的依据是:发送窗口=min[接收窗口,拥塞窗口]
C. 拥塞窗口是接收端根据网络拥塞情况确定的窗口值
D. 拥塞窗口大小在开始时可以按指数规律增长
答案:C
2、一个TCP连接总是以1KB的最大段长发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为34KB时发生了超时,如果接下来的4个RTT内的TCP段的传输都是成功的,那么当第4个RTT时间内发送的所有TCP段都得到肯定应答时,拥塞窗口的大小是
A. 8KB
B. 9KB
C. 16KB
D. 17KB
答案:C
解析: 发生超时后,将慢开始门限值更新为当前拥塞窗口的一半,即17KB。然后将拥塞窗口设置为1,开始传输数据。第1个RTT结束后,拥塞窗口为2KB。第2个RTT结束后,拥塞窗口为4KB。第3个RTT结束后,拥塞窗口为8KB。第4个RTT结束后,拥塞窗口为16KB。
3、设TCP拥塞窗口的慢开始门限初始值为8(单位为TCP报文段),当拥塞窗口上升到12时发生超时,则第13个传输轮次时拥塞窗口的大小为
A. 4
B. 5
C. 6
D. 7
答案:D
解析: 拥塞窗口从初始值1达到慢开始门限值8,经过了4个RTT(1,2,4,8)。拥塞窗口从慢开始门限值8到达12,经过了4个RTT(9,10,11,12)。此时慢开始门限值更新为当前拥塞窗口的一半,即6。拥塞窗口从1开始重新指数增长,增长到6时经过了4个RTT(1,2,4,6)。所以第13个RTT时,拥塞窗口大小就是6+1=7。
4、一个TCP连接总是以1KB的最大段长发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为34KB时收到了3个重复的ACK报文,如果接下来的4个RTT内的TCP段的传输都是成功的,那么当第4个RTT时间内发送的所有TCP段都得到肯定应答时,拥塞窗口的大小是
A. 8KB
B. 16KB
C. 20KB
D. 21KB
答案:D
解析: 收到3个重复的ACK报文后,将拥塞窗口调整为当前的一半,即17。接下来,第1个RTT结束后,拥塞窗口为18KB。第2个RTT结束后,拥塞窗口为19KB。第3个RTT结束后,拥塞窗口为20KB。第4个RTT结束后,拥塞窗口为21KB。
5、主机甲和乙建立了TCP连接,甲始终以1KB大小的段发送数据,并一直有数据发送;乙每收到一个数据段都会发出一个接收窗口为10KB的确认段。若甲在t时刻发生超时的时候拥塞窗口为16KB,则从t时刻起,不再发生超时的情况下,经过10个RTT后,甲的发送窗口是
A. 10KB
B. 12KB
C. 14KB
D. 15KB
答案:A
解析: 发生超时后,将慢开始门限值更新为当前拥塞窗口的一半,即8KB。然后将拥塞窗口设置为1,开始传输数据。第1个RTT结束后,拥塞窗口为2KB。第2个RTT结束后,拥塞窗口为4KB。第3个RTT结束后,拥塞窗口为8KB。第4个RTT结束后,拥塞窗口超过了乙的接收窗口,而拥塞窗口=min[接收窗口,拥塞窗口],所以后面的RTT中拥塞窗口一直会保持为10KB。