- 运输层概述
1.1 课后练习
- 运输层端口、复用与分用的概念
2.1 课后练习
- UDP和TCP的对比
3.1 总结
3.2 课后练习
- 运输层概述
■ 之前的计算机网络体系结构中的物理层、数据链路层以及网络层它们共同解决了将主机通过异构网络互联起来所面临的问题,实现了主机到主机的通信。
■ 但实际上在计算机网络中进行通信的真正实体是位于通信两端主机中的进程。
■ 如何为运行在不同主机上的应用进程提供直接的通信服务是运输层的任务,运输层协议又称为端到端协议。
在这里插入图片描述
下图从计算机网络体系结构的角度来看运输层。AP1、AP2、AP3、AP4是通信双方应用层中的应用进程,假设AP1与AP4之间进行基于网络的通信,AP2与AP3之间进行基于网络的通信。在运输层使用不同的端口来对应不同的应用进程,然后通过网络层及其下层来传输应用层报文。接收方的运输层通过不同的端囗将收到的应用层报文交付给应用层中相应的应用进程。需要注意的是,这里的端口并不是指看得见摸得着的物理端口,而是指用来区分不同应用进程的标识符。为了简单起见,在学习和研究运输层时,我们可以简单的认为运输层直接为应用进程间的逻辑通信提供服务。"逻辑通信"的意思是,运输层之间的通信好像是沿水平方向传送数据,但事实上这两个运输层之间并没有一条水平方向的物理连接,要传送的数据是沿着图中上下多次的虚线方向传送的。
在这里插入图片描述
运输层向高层用户屏蔽了下面网络核心的细节(如网络拓扑、所采用的路由选择协议等),它使应用层看见的就好像是在两个运输层实体之间有一条端到端的逻辑通信信道。
根据应用需求的不同,因特网的运输层为应用层提供了两种不同的运输层协议,即面向连接的TCP和无连接的UDP。
1.1 课后练习
- 运输层为( B )之间提供逻辑通信服务。
A. 主机 B. 进程 C. 路由器 D. 操作系统
分析: 运输层为进程之间提供逻辑通信服务。
- 在TCP/IP体系结构中,运输层的主要作用是在互联网络的源主机和目的主机对等实体之间建立用于会话的( C )
A. 点到点连接 B. 操作连接 C. 端到端连接 D. 控制连接
分析: 在TCP/IP体系结构中,运输层的主要作用是在互联网络的源主机和目的主机对等实体之间建立用于会话的端到端连接。
- 运输层端口、复用与分用的概念
■ 运行在计算机上的进程使用进程标识符PID来标志。
■ 因特网上的计算机并不是使用统一的操作系统,不同的操作系统(windows,Linux,Mac oS)又使用不同格式的进程标识符。
■ 为了使运行不同操作系统的计算机的应用进程之间能够进行网络通信,就必须使用统一的方法对TCP/IP体系的应用进程进行标识。
■ TCP/IP体系的运输层使用端口号来区分应用层的不同应用进程。
⋄ \diamond ⋄ 端口号使用16比特表示,取值范围0~65535;
∘ \circ ∘ 熟知端口号:0~1023,因特网数字分配机构IANA把这些端口号指派给了TCP/IP体系中最重要的一些应用协议,例如:FTP使用21/20,HTTP使用80,DNS使用53。
∘ \circ ∘ 登记端口号: 1024~49151,为没有熟知端口号的应用程序使用。使用这类端口号必须在IANA按照规定的手续登记,以防止重复。例如:Microsoft RDP微软远程桌面使用的端口是3389。
∘ \circ ∘ 短暂端口号: 49152~65535,留给客户进程选择暂时使用。当服务器进程收到客户进程的报文时,就知道了客户进程所使用的动态端口号。通信结束后,这个端口号可供其他客户进程以后使用。
⋄ \diamond ⋄ 端口号只具有本地意义,即端口号只是为了标识本计算机应用层中的各进程,在因特网中,不同计算机中的相同端口号是没有联系的。
■ 发送方的复用和接收方的分用
如下图所示,对于收发双方的应用进程,发送方的某些应用进程所发送的不同应用报文,在运输层使用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体系的应用层常用协议所使用的运输层熟知端口号
在这里插入图片描述
2.1 课后练习
- 在TCP/IP中,采用( A )来区分不同的应用进程。
A. 端口号 B. IP地址 C. 协议类型 D. MAC地址
分析: 在TCP/IP中,采用端口号来区分不同的应用进程。
- 在TCP/IP网络中,为各种熟知应用保留的端口号范围是( B)
A. 1~255 B. 0~1023 C. 1~1024 D. 1~65535
分析: 熟知端口号:0~1023,因特网数字分配机构IANA把这些端口号指派给了TCP/IP体系中最重要的一些应用协议。
- 在TCP/IP中,运输层端口号的范围是( D)
A. 1~255 B. 0~1023 C. 1~1024 D. 1~65535
分析: TCP/IP体系的运输层使用端口号来区分应用层的不同应用进程,端口号使用16比特表示,取值范围0~65535。
- UDP和TCP的对比
■ UDP和TCP是TCP/IP体系结构运输层中的两个重要协议
下图所示的是TCP/IP体系结构,运输层有两个非常重要的协议UDP和TCP。在使用TCP/IP体系结构的网络通信中,这两个协议的使用频率仅次于网际层的IP协议。TCP/IP体系结构应用层中的某些协议需要使用运输层的TCP提供的服务,而另一些协议需要使用运输层的UDP提供的服务,UDP是用户数据报协议的英文缩写词,TCP是传输控制协议的英文缩写词。
在这里插入图片描述
下表给出了一些应用和应用层协议主要使用的运输层协议(UDP或TCP)。
使用UDP和TCP协议的各种应用和应用层协议
在这里插入图片描述
接下来从几个方面对这两个协议进行比较。
对比1: 如下图所示,左边是因特网上的两台主机,它们在运输层使用UDP协议进行通信,纵坐标为时间,使用UDP协议的通信双方可以随时发送数据。
右边是使用TCP协议的情况,使用TCP协议的通信双方在进行数据传输之前,必须使用"三报文握手"来建立TCP连接,TCP连接建立成功后才能进行数据传输。数据传输结束后,必须使用"四报文挥手"来释放TCP连接。"三报文握手"和"四报文挥手"属于TCP的连接管理,其过程比较复杂。需要注意的是,这里所谓的连接是指逻辑连接关系,而不是物理连接。综上所述,UDP是无连接的,而TCP是面向连接的。
在这里插入图片描述
对比2: 如下图所示,左边是某个局域网上的、使用UDP协议进行通信的四台主机。其中任何一台主机都可向其他三台主机发送广播,也可以向某个多波组发送多波,还可以向某台主机发送单波,也就是说UDP支持单播、多播以及广播。换句话说,UDP支持一对一、一对多以及一对全的通信。
右边是使用TCP协议的情况,使用TCP协议的通信双方在进行数据传输之前,必须使用"三报文握手"来建立TCP连接,TCP连接建立成功后通信双方之间就好像有一条可靠的通信信道。通信双方使用这条基于TCP连接的可靠信道进行通信。很显然,TCP仅支持单播,也就是一对一的通信。
在这里插入图片描述
对比3: 接下来对比这两个协议对应用报文的处理。如下图所示,左边是使用UDP协议的情况,发送方的应用进程将应用层报文交付给运输层的UDP。UDP直接给应用层报文添加一个UDP首部,使之成为UDP用户数据报,然后进行发送。需要说明的是,为了简单起见,我们忽略运输层下面的各层处理。接收方的UDP收到该UDP用户数据报后,去掉UDP首部,将应用层报文交付给应用进程,也就是说UDP对应用进程交下来的报文既不合并也不拆分,而是保留这些报文的边界。换句话说,UDP是面向应用报文的。
右边是使用TCP协议的情况,发送方的TCP把应用进程交付下来的数据块仅仅看作是一连串的、无结构的字节流。TCP并不知道这些待传送的字节流的含义,仅将它们编号并存储在自己的发送缓存中。TCP根据发送策略,从发送缓存中提取一定数量的字节,构建TCP报文段并发送。接收方的TCP一方面从所接收到的TCP报文段中取出数据载荷部分并存储在接收缓存中,一方面将接收缓存中的一些字节交付给应用进程。TCP不保证接收方应用进程所收到的数据块与发送方应用进程所发出的数据块具有对应大小的关系,例如发送方应用进程交给发送方的TCP共10个数据块,但接收方的TCP可能只用了4个数据块就把收到的字节流交付给了上层的应用进程,但接收方应用进程收到的字节流必须和发送方应用进程发出的字节流完全一样。当然,接收方的应用进程必须有能力识别收到的字节流,把它还原成有意义的应用层数据,也就是说TCP是面向字节流的。这正是TCP实现可靠传输流量控制以及拥塞控制的基础。
在这里插入图片描述
对比4: 如下图所示,左边是使用UDP协议的情况。TCP/IP体系结构的网际层向其上层提供的是无连接不可靠的传输服务。当运输层使用UDP协议时,向其上层提供的也是无连接不可靠的传输服务。发送方给接收方发送UDP用户数据报,若传输过程中,用户数据报受到干扰而产生误码,接收方UDP可以通过该数据报首部中的校验和字段的值,检查出产生误码的情况,但仅仅丢弃该数据报,其他什么也不做。发送方给接收方发送UDP用户数据报,如果该数据报被因特网中的某个路由器丢弃了,发送方UDP不做任何处理。因为UDP向上层提供的是无连接不可靠的传输服务,因此对于UDP用户数据报出现的误码和丢失等问题,UDP并不关心。基于UDP的这个特点,UDP适用于实时应用,例如IP电话视频会议等。
右边是使用TCP协议的情况,尽管网际层中的IP协议向上层提供的是无连接不可靠的传输服务,也就是说IP数据报可能在传输过程中出现丢失或误码,但只要运输层使用TCP协议就可向其上层提供面向连接的可靠传输服务。我们可将其想象成,使用TCP协议的收发双方基于TCP连接的可靠信道进行数据传输,不会出现误码、丢失、乱序以及重复等传输差错。TCP适用于要求可靠传输的应用,例如文件传输。
在这里插入图片描述
对比5: 最后对比一下UDP用户数据报的首部与TCP报文段的首部。如下图所示,左边是使用UDP协议的情况,一个UDP用户数据报由首部和数据载荷两部分构成。其首部格式如图所示,仅有4个字段,每个字段长度为2个字节。由于UDP不提供可靠传输服务,它仅仅在网际层的基础上添加了用于区分应用进程的端口,因此它的首部非常简单,仅有8个字节。
右边是使用TCP协议的情况,一个TCP报文段由首部和数据载荷两部分构成。其首部格式如图所示,比UDP用户数据报的首部复杂的多,且最小长度为20字节,最大长度为60字节。这是因为TCP要实现可靠传输、流量控制拥塞控制等服务,其首部自然会比较复杂,首部中的字段比较多,首部长度也比较长。
在这里插入图片描述
3.1 总结
在这里插入图片描述
3.2 课后练习
- 以下字段包含在TCP首部中而不包含在UDP首部中的是( B )
A. 目标端口号 B. 序号 C. 源端口号 D. 校验和
分析: 以下字段包含在TCP首部中而不包含在UDP首部中的是序号。
- 若接收端收到有差错的UDP用户数据报,则会( A )
A. 将其丢弃 B. 请求重传 C. 纠错 D. 忽略差错
分析: 若接收端收到有差错的UDP用户数据报,则会将其丢弃。
当运输层使用UDP协议时,向其上层提供的是无连接不可靠的传输服务。发送方给接收方发送UDP用户数据报,若传输过程中,用户数据报受到干扰而产生误码,接收方UDP可以通过该数据报首部中的校验和字段的值,检查出产生误码的情况,但仅仅丢弃该数据报,其他什么也不做。
- UDP用户数据报比IP数据报多提供了( C )
A. 流量控制功能 B. 拥塞控制功能 C. 端口功能 D. 路由转发功能
分析: UDP用户数据报比IP数据报多提供了端口功能。
- 下列不属于TCP特点的是( D )
A. 面向字节流 B. 全双工 C. 可靠 D. 支持广播
分析: TCP特点:面向字节流、全双工、可靠。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/HUAI_BI_TONG/article/details/118640612
- TCP的流量控制
4.1 课后练习
- TCP的拥塞控制
5.1 慢开始(slow-start)
5.2 拥塞避免(congestion avoidance)
5.3 快重传(fast retransmit)
5.4 快恢复(fast recovery)
5.5 课后练习
- TCP的流量控制
■ 一般来说,我们总是希望数据传输得更快一些。
⋄ \diamond ⋄ 但如果发送方把数据发送得过快,接收方就可能来不及接收,这就会造成数据的丢失。
■ 所谓流量控制(flow control)就是让发送方的发送速率不要太快,要让接收方来得及接收。
■ 利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制。
⋄ \diamond ⋄ TCP接收方利用自己的接收窗口的大小来限制发送方发送窗口的大小。
⋄ \diamond ⋄ 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对主机A所发送的201号以前的数据进行累计确认,并在该累计确认中将窗口字段的值调整为300,也就是对主机A进行流量控制。
在这里插入图片描述
ACK是TCP报文段首部中的标志位,取值1表示这是一个TCP确认报文段;ack是TCP报文段首部中的确认号字段,取值201表示序号201之前的数据已全部正确接收,现在希望收到序号201及其后续数据;rwnd是TCP报文段首部中的窗囗字段,取值300表示自己的接收窗大小为300。
主机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进行的第二次流量控制。
在这里插入图片描述
主机A收到该累计确认后,将发送窗口向前滑动,使已发送并收到确认的这些数据的序号移出发送窗口。由于主机B在该累计确认中将自己的接收窗口调整为了100,因此主机A相应的将自己的发送窗口调整为100。目前主机A发送窗口内的序号为501 ~ 600,也就是主机还可以发送这100字节。主机A现在可将发送缓存中序号201 ~ 500的字节数据全部删除了,因为已经收到了主机B对它们的累计确认。主机A将发送窗口内序号501 ~ 600的数据封装成一个TCP报文段发送出去。至此,序号落在发送窗口内的数据已经全部发送出去了,不能再发送新数据了。主机B对主机A所发送的601号以前的数据进行累计确认,在该累计确认中将窗口字段的值调整为0,这是主机B对主机A进行的第三次流量控制。
在这里插入图片描述
主机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立刻发送一个仅携带一字节数据的零窗口探测报文段。假设主机B此时的接收窗口又为0了,主机B就在确认这个零窗口探测报文段时,给出自己现在的接收窗口值为0。主机A再次收到零窗口通知,就再次启动一个持续计时器。当持续计时器超时,主机A立刻发送一个零窗口探测报文段。假设主机B此时的接收缓存又有了一些存储空间,于是将自己的接收窗调整为300,主机B就在确认这个零窗口探测报文段时,给出自己现在的接收窗口值为300,这样就打破了死锁的局面。
在这里插入图片描述
问题: 主机A所发送的零窗口探测报文段到达主机B时,如果主机B此时的接收窗口仍然为0,那么主机B根本就无法接受该报文段,又怎么会针对该报文段给主机A发回确认呢?
实际上TCP规定:即使接收窗口为0,也必须接受零窗口探测报文段、确认报文段以及携带有紧急数据的报文段。
思考: 如果零窗口探测报文段丢失了,会出现怎样的问题呢?还能否打破死锁的局面呢?
在这里插入图片描述
回答是肯定的。因为零窗口探测报文段也有重传计时器,当重传计时器超时后,零窗口探测报文段会被重传。
例: 主机甲和主机乙之间建立了一个TCP连接,TCP最大段长度为1000字节。若主机甲的当前拥塞窗口为4000字节,在主机甲向主机乙连续发送两个最大段后,成功收到主机乙发送的第一个段的确认段,确认段中通告的接收窗口大小为2000字节,则此时主机甲还可以向主机乙发送的最大字节数是( A )
A.1000 B.2000 C.3000 D.4000
分析:
在这里插入图片描述
4.1 课后练习
- 在采用TCP连接的数据传输阶段,如果发送端的发送窗口值由1000变为2000,那么发送端在收到一个确认之前可以发送( B )
A. 2000个TCP报文段 B. 2000B C. 1000B D. 1000个TCP报文段
分析: 在采用TCP连接的数据传输阶段,如果发送端的发送窗口值由1000变为2000,那么发送端在收到一个确认之前可以发送2000B。
- A和B建立了TCP连接,当A收到确认号为100的TCP确认报文段时,表示( C )
A. 已收到99号TCP报文段
B. 已收到100号TCP报文段
C. 已收到数据载荷部分最后一字节序号为99的TCP报文段
D. 已收到数据载荷部分最后一字节序号为100的TCP报文段
分析: A和B建立了TCP连接,当A收到确认号为100的TCP确认报文段时,表示已收到数据载荷部分最后一字节序号为99的TCP报文段。
- 在TCP协议中,发送方的窗口大小取决于( C )
A. 仅接收方允许的窗口
B. 接收方允许的窗口和发送方允许的窗口
C. 接收方允许的窗口和拥塞窗口
D. 发送方允许的窗口和拥塞窗口
分析: 在TCP协议中,发送方的窗口大小取决于接收方允许的窗口和拥塞窗口。
- 主机甲和主机乙之间建立了一个TCP连接,TCP最大段长度为1000字节,若主机甲当前发送窗口为6000字节,不考虑拥塞窗口,在主机甲向主机乙连续发送三个最大段后,成功收到主机乙发送的第一个段的确认段,确认段中通告的接收窗口大小为4000字节,则此时主机甲还可以向主机乙发送的最大字节数是( B )
A. 1000 B. 2000 C. 3000 D. 4000
- TCP的拥塞控制
■ 在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络性能就要变坏。这种情况就叫做拥塞(congestion)。
⋄ \diamond ⋄ 在计算机网络中的链路容量(即带宽)、交换结点中的缓存和处理机等,都是网络的资源。
■ 若出现拥塞而不进行控制,整个网络的吞吐量将随输入负荷的增大而下降。
在这里插入图片描述
■ 四种拥塞控制算法: 慢开始、拥塞避免、快重传、快恢复。
下面介绍这四种拥塞控制算法的基本原理,假定如下条件:
-
数据是单方向传送,而另一个方向只传送确认。
-
接收方总是有足够大的缓存空间,因而发送方发送窗口的大小由网络的拥塞程度来决定。
-
以最大报文段MSS的个数为讨论问题的单位,而不是以字节为单位。
如下图所示,假设左右分别是TCP的发送方和接收方,发送方给接收方发送TCP数据报文段,接收方收到后,给发送方发送TCP确认报文段。发送方要维护一个叫做拥塞窗口的状态变量,其值取决于网络的拥塞程度,并且动态变化。拥塞窗口的维护原则是只要网络没有出现拥塞,拥塞窗口就再增大一些,但只要网络出现拥塞,拥塞窗口就减小一些。
在这里插入图片描述
判断出现网络拥塞的依据是没有按时收到应当到达的确认报文段,也就是发生了超时重传。发送方将拥塞窗口作为发送窗口,也就是发送窗口等于拥塞窗口。发送方还需要维护一个叫做慢开始门限的状态变量,当拥塞窗口小于慢开始门限时,使用慢开始算法;当拥塞窗口大于慢开始门限时,停止使用慢开始算法,而改用拥塞避免算法;当拥塞窗口等于慢开始门限时,既可以使用慢开始算法,也可以使用拥塞避免算法。
■ 发送方维护一个叫做拥塞窗口cwnd的状态变量,其值取决于网络的拥塞程度,并且动态变化。
⋄ \diamond ⋄ 拥塞窗口cwnd的维护原则: 只要网络没有出现拥塞,拥塞窗口就再增大一些;但只要网络出现拥塞,拥塞窗口就减少一些。
⋄ \diamond ⋄ 判断出现网络拥塞的依据:没有按时收到应当到达的确认报文(即发生超时重传)。
■ 发送方将拥塞窗口作为发送窗口swnd,即swnd = cwnd。
■ 维护一个慢开始门限ssthresh状态变量:
⋄ \diamond ⋄ 当cwnd < ssthresh时,使用慢开始算法;
⋄ \diamond ⋄ 当cwnd > ssthresh时,停止使用慢开始算法而改用拥塞避免算法;
⋄ \diamond ⋄ 当cwnd = ssthresh时,既可使用慢开始算法,也可使用拥塞避免算法。
5.1 慢开始(slow-start)
对于慢开始算法,为了更清楚的显示出拥塞控制过程,可以绘制如下所示的拥塞窗口随传输轮次变化的图,横坐标为传输轮次。传输轮次是指发送方给接收方发送数据报文段后,接收方给发送方发回相应的确认报文段,一个传输轮次所经历的时间其实就是往返时间。请注意,往返时间并非是恒定的数值。使用传输轮次是为了强调把拥塞窗口所允许发送的报文段都连续发送出去,并收到了对已发送的最后一个报文段的确认。
纵坐标是拥塞窗口,它会随网络拥塞程度以及所使用的拥塞控制算
法动态变化。在TCP双方建立逻辑连接关系时,拥塞窗口的值被设置为1。在图上标出传输轮次0时的拥塞窗口值为1。另外,还需设置慢开始门限的初始值,本例采用16,并将它在图中标出。在执行慢开始算法时,发送方每收到一个对新报文段的确认时,就把拥塞窗口值加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,而不像慢开始算法那样,每个传输轮次结束后,拥塞窗口值按指数规律增长。
5.2 拥塞避免(congestion avoidance)
发送方现在可以发送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开始按指数规律增大,当增大到了新的慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。
在这里插入图片描述
■ "慢开始"是指一开始向网络注入的报文段少,而并不是指拥塞窗口值增长速度慢。
■ "拥塞避免"也并非指完全能够避免拥塞,而是只在拥塞避免阶段,将拥塞窗口值控制为按线性规律增长,使网络比较不容易出现拥塞。
■ 慢开始和拥塞避免是1988年就提出的TCP拥塞控制算法(TCP Tahoe版本)。
■ 1990年又增加了两个新的拥塞控制算法,以便改进TCP的性能,这就是快重传和快恢复(TCP Reno版本)。
⋄ \diamond ⋄ 有时,个别报文段会在网络中丢失,但实际上网络并未发生拥塞。
∘ \circ ∘ 这将导致发送方超时重传,并误认为网络发生了拥塞;
∘ \circ ∘ 例如,在之前的例子中,当拥塞窗口值增大到24时,发生了超时重传,而网络此时并没有发生拥塞,但是发送方却误认为网络发生了拥塞,于是发送方把拥塞窗口值减小为1,并错误的启动慢开始算法,因而降低了传输效率。
在这里插入图片描述
■ 采用快重传算法可以让发送方尽早知道发生了个别报文段的丢失。
5.3 快重传(fast retransmit)
■ 所谓快重传,就是使发送方尽快进行重传而,不是等超时重传计时器超时再重传。
⋄ \diamond ⋄ 这就要求接收方不要等待自己发送数据时才进行捎带确认,而是要立即发送确认;
⋄ \diamond ⋄ 即使收到了失序的报文段也要立即发出对已收到的报文段的重复确认。
⋄ \diamond ⋄ 发送方一旦收到3个连续的重复确认,就将相应的报文段立即重传,而不是等该报文段的重传计时器超时再重传。
⋄ \diamond ⋄ 对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞(进而降低拥塞窗口cwnd为1)。使用快重传可以使整个网络的吞吐量提高约20%。
举例说明快重传算法。
发送方发送1号数据报文段,接收方收到后,给发送方发回对1号报文段的确认。
在该确认报文段到达发送方之前,发送方还可以将发送窗口内的2号数据报文段发送出去,接收方收到后,给发送方发回对2号报文段的确认。
在该确认报文段到达发送方之前,发送方还可以将发送窗口内的3号数据报文段发送出去,但该报文段丢失了,接收方自然不会给发送方发回针对该报文段的确认。
发送方还可以将发送窗口内的4号数据报文段发送出去,接收方收到后,发现这不是按序到达的报文段,因此给发送方发回针对2号报文段的重复确认,表明:"我现在希望收到的是3号报文段,但是我没有收到3号报文段,而是收到了未按序到达的报文段。"
发送方还可以将发送窗口内的5号数据报文段发送出去,接收方收到后,发现这不是按序到达的报文段,因此给发送方发回针对2号报文段的重复确认。
发送方还可以将发送窗口内的6号数据报文段发送出去,接收方收到后,发现这不是按序到达的报文段,因此给发送方发回针对2号报文段的重复确认。
至此,发送方会收到3个连续的对2号报文段的重复确认,就立即重传3号报文段,接收方收到后,给发送方发回针对6号报文段的确认,表明序号到6为止的报文段都正确接收了。这样就不会造成对3号报文段的超时重传,而是提早进行了重传。
在这里插入图片描述
对于个别丢失的报文段,发送方不会出现超时重传,也就不会误认为出现了拥塞而错误的降低拥塞窗口值为最小值1。使用快重传可以使整个网络的吞吐量提高约20%。
5.4 快恢复(fast recovery)
■ 发送方一旦收到3个重复确认,就知道现在只是丢失了个别的报文段。于是不启动慢开始算法,而执行快恢复算法;
⋄ \diamond ⋄ 发送方将慢开始门限ssthresh值和拥塞窗口cwnd值调整为当前窗口的一半,开始执行拥塞避免算法。
⋄ \diamond ⋄ 也有的快恢复实现是把快恢复开始时的拥塞窗口cwnd值再增大一些,即等于新的ssthresh + 3。
∘ \circ ∘ 既然发送方收到3个重复的确认,就表明有3个数据报文段已经离开了网络;
∘ \circ ∘ 这3个报文段不再消耗网络资源而是停留在接收方的接收缓存中;
∘ \circ ∘ 可见现在网络中不是堆积了报文段,而是减少了3个报文段,因此可以适当把拥塞窗口扩大些。
接下来,给出TCP拥塞窗口值在拥塞控制时的变化情况举例,里面包含了TCP拥塞控制的四种算法。TCP发送方一开始使用慢开始算法,让拥塞窗口值从1开始按指数规律增大,当增大到慢开始门限初始值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。当发生超时重传时,就判断网络可能出现了拥塞,采取相应的措施。一方面,将慢开始门限值更新为发生拥塞时拥塞窗囗值的一半;另一方面,将拥塞窗口值减小为1,并重新开始执行慢开始算法。拥塞窗口值又从1开始按指数规律增大,当增大到了新的慢开始门限值时,停止使用慢开始算法,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。当发送方收到3个重复的确认时,就进行快重传和快恢复,也就是更新慢开始门限值为当前拥塞窗口值的一半,并将拥塞窗口值也取为新的慢开始门限值,转而执行拥塞避免算法,让拥塞窗口值按线性加1的规律增大。
在这里插入图片描述
例: 一个TCP连接总是以1KB的最大段长发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为16KB时发生了超时,如果接下来的4个RTT(往返时间)内的TCP段的传输都是成功的,那么当第4个RTT时间内发送的所有TCP段都得到肯定应答时,拥塞窗口大小是( C )
A. 7KB B. 8KB C. 9KB D. 16KB
分析:
在这里插入图片描述
5.5 课后练习
- 以下关于TCP窗口与拥塞控制概念的描述中,错误的是( C )
A. 接收窗口通过TCP首部中的窗口字段通知数据的发送方
B. 发送窗口确定的依据是:发送窗口=min[接收窗口,拥塞窗口]
C. 拥塞窗口是接收端根据网络拥塞情况确定的窗口值
D. 拥塞窗口大小在开始时可以按指数规律增长
分析: 拥塞窗口是发送端根据网络拥塞情况确定的窗口值,发送端在真正确定发送窗口时,应该取"通知窗口"和"拥塞窗口"的最小值。
- 一个TCP连接总是以1KB的最大段长发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为34KB时发生了超时,如果接下来的4个RTT内的TCP段的传输都是成功的,那么当第4个RTT时间内发送的所有TCP段都得到肯定应答时,拥塞窗口的大小是( C )
A. 8KB B. 9KB C. 16KB D.17KB
分析: 当拥塞窗口为34KB时发生了超时,ssthresh更新值=34/ 2 = 17,更新cwnd的值为1,并开始重新执行慢开始算法。接下来的4个RTT内的TCP段的传输都是成功的,拥塞窗口的大小依次是1→2→4→8→16。
- 设TCP拥塞窗口的慢开始门限初始值为8(单位为TCP报文段),当拥塞窗口上升到12时发生超时,则第13个传输轮次时拥塞窗口的大小为( D )
A. 4 B. 5 C. 6 D. 7
分析: TCP拥塞窗口的慢开始门限初始值为8,当拥塞窗口上升到12时发生超时,ssthresh更新值=12/ 2 = 6,更新cwnd的值为1,并开始重新执行慢开始算法。13个传输轮次时拥塞窗口的大小依次是1→2→4→8→9→10→11→12→1→2→4→5→6→7。
- 一个TCP连接总是以1KB的最大段长发送TCP段,发送方有足够多的数据要发送。当拥塞窗口为34KB时收到了3个重复的ACK报文,如果接下来的4个RTT内的TCP段的传输都是成功的,那么当第4个RTT时间内发送的所有TCP段都得到肯定应答时,拥塞窗口的大小是( D )
A. 8KB B. 16KB C. 20KB D. 21KB
分析: 当拥塞窗口为34KB时收到了3个重复的ACK报文,ssthresh更新值=34/ 2 = 17,更新cwnd的值为ssthresh的值
,转而执行拥塞避免算法。接下来的4个RTT内的TCP段的传输都是成功的,拥塞窗口的大小依次是17→18→19→20→21。
- 主机甲和乙建立了TCP连接,甲始终以1KB大小的段发送数据,并一直有数据发送;乙每收到一个数据段都会发出一个接收窗口为10KB的确认段。若甲在t时刻发生超时的时候拥塞窗口为16KB,则从t时刻起,不再发生超时的情况下,经过10个RTT后,甲的发送窗口是( A )
A. 10KB B. 12KB C. 14KB D. 15KB
分析: 若甲在t时刻发生超时的时候拥塞窗口为8KB,把慢开始门限值设为当前窗口的一半,即ssthresh=16/2 =8KB,更新cwnd的值为1,并开始重新执行慢开始算法。拥塞窗口的大小依次是1→2→4→8→9→10→...,经过5个RTT cwnd=10KB, 因为发送端不能超过接收端10KB,此后拥塞窗口一直保持cwnd=10KB。
发送窗口大小=min(接收窗口,拥塞窗口)=10KB。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/HUAI_BI_TONG/article/details/118651119
- TCP超时重传时间的选择
6.1 课后练习
- TCP可靠传输的实现
7.1 课后练习
- TCP超时重传时间的选择
■ 超时重传时间的选择是TCP最复杂的问题之一
如下图所示,假设主机A和B是因特网上的两台主机,它们之间已经建立了TCP连接,纵坐标为时间。现在,主机A给主机B发送TCP数据报文段0,并记录下当前的时间,主机B收到后给主机A发送相应的确认报文段,主机A收到确认报文段后记录下当前的时间。主机A记录下的这两个时间,它们的差值就是报文段的往返时间RTT。由于这是第0个报文段的RTT,我们就用RTT0来表示。
在这里插入图片描述
试想一下,如果我们将超时重传时间RTO的值设置的比RTT0的值小,会出现怎样的情况呢?
很显然,这会引起报文段不必要的重传,使网络负荷增大。
在这里插入图片描述
那么,如果将超时重传时间RTO的值设置的远大于RTT0的值,又会出现怎样的情况呢?
很显然,这会使重传推迟的时间太长,使网络的空闲时间增大,降低了传输效率。
在这里插入图片描述
综合上述两种情况,我们可以得出结论:超时重传时间RTO的值应该设置为略大于报文段往返时间RRT的值。
在这里插入图片描述
■ 不能直接使用某次测量得到的RTT样本来计算超时重传时间RTO。
■ 利用每次测量得到的RTT样本,计算加权平均往返时间 RTT S _S S(又称为平滑的往返时间)。
在这里插入图片描述
■ 用这种方法得出的加权平均往返时间RTT S _S S就比测量出的RTT值更加平滑。
■ 显然,超时重传时间RTO应略大于加权平均往返时间RTTs。
■ RFC6298建议使用下式计算超时重传时间RTO:
在这里插入图片描述
由上我们可以发现,不管是RTT S _S S还是RTT D _D D都是基于所测量到的RTT样本进行计算的。如果所测量到的RTT样本不正确,那么所计算出的RTT S _S S和RTT D _D D自然就不正确,进而所计算出的超时重传时间RTO也就不正确。
■ 往返时间RTT的测量比较复杂
在这里插入图片描述
■ 针对出现超时重传时无法测准往返时间RTT的问题,Karn提出了一个算法:在计算加权平均往返时间RTTs时,只要报文段重传了,就不采用其往返时间RTT样本。也就是出现重传时,不重新计算RTT S _S S,进而超时重传时间RTO也不会重新计算。
⋄ \diamond ⋄ 这又引起了新的问题。设想出现这样的情况:报文段的时延突然增大了很多,并且之后很长一段时间都会保持这种时延。因此在原来得出的重传时间内,不会收到确认报文段。于是就重传报文段。但根据Karn算法,不考虑重传的报文段的往返时间样本。这样,超时重传时间就无法更新。这会导致报文段反复被重传。
■ 因此,要对Karn算法进行修正。方法是:报文段每重传一次,就把超时重传时间RTO增大一些。典型的做法是将新RTO的值取为旧RTO值的2倍,即出现超时重传时,新RTO=2倍的旧RTO。
6.1 课后练习
- 以下关于TCP超时重传时间RTO的叙述中,正确的是( D )
A. RTO应小于TCP端到端加权平均往返时间RTTs
B. RTO应远大于TCP端到端加权平均往返时间RTTs
C. RTO应等于TCP端到端加权平均往返时间RTTs
D. RTO应略大于TCP端到端加权平均往返时间RTTs
分析: RTO应略大于TCP端到端加权平均往返时间RTTs。
- 若出现超时重传,则以下关于TCP超时重传时间RTO的叙述中,正确的是( B )
A. RTO的值应清零
B. RTO的值应扩大两倍
C. RTO的值应减1
D. RTO的值应保持不变
分析: 若出现超时重传,RTO的值应扩大两倍。
- TCP可靠传输的实现
■ TCP基于以字节为单位的滑动窗口来实现可靠传输。
⋄ \diamond ⋄ 发送方在未收到接收方的确认时,可将发送窗口内还未发送的数据全部发送出去;
⋄ \diamond ⋄ 接收方只接收序号落入发送窗口内的数据。
■ 虽然发送方的发送窗口是根据接收方的接收窗口设置的,但在同一时刻,发送方的发送窗口并不总是和接收方的接收窗口一样大。
⋄ \diamond ⋄ 网络传送窗口值需要经历一定的时间滞后,并且这个时间还是不确定的。
⋄ \diamond ⋄ 发送方还可能根据网络当时的拥塞情况适当减小自己的发送窗口尺寸。
■ 对于不按序到达的数据应如何处理,TCP并无明确规定。
⋄ \diamond ⋄ 如果接收方把不按序到达的数据一律丢弃,那么接收窗口的管理将会比较简单,但这样做对网络资源的利用不利,因为发送方会重复传送较多的数据。
⋄ \diamond ⋄ TCP通常对不按序到达的数据是先临时存放在接收窗口中,等到字节流中所缺少的字节收到后,再按序交付上层的应用进程。
■ TCP要求接收方必须有累积确认和捎带确认机制,这样可以减小传输开销。接收方可以在合适的时候发送确认,也可以在自己有数据要发送时把确认信息顺便捎带上。
⋄ \diamond ⋄ 接收方不应过分推迟发送确认,否则会导致发送方不必要的超时重传,这反而浪费了网络的资源。
TCP标准规定,确认推迟的时间不应超过0.5秒。若收到一连串具有最大长度的报文段,则必须每隔一个报文段就发送一个确认[RFC 1122]。
⋄ \diamond ⋄ 捎带确认实际上并不经常发生,因为大多数应用程序很少同时在两个方向上发送数据。
■ TCP的通信是全双工通信。 通信中的每一方都在发送和接收报文段。因此,每一方都有自己的发送窗口和接收窗口。
例1: 主机甲与主机乙之间已建立一个TCP连接,主机甲向主机乙发送了两个连续的TCP段,分别包含300字节和500字节的有效载荷,第一个段的序号为200,主机乙正确接收到两个段后,发送给主机甲的确认序号是( D )
A. 500 B. 700 C. 800 D. 1000
分析:
在这里插入图片描述
例2: 【2011年题40】主机甲与主机乙之间已建立一个TCP连接,主机甲向主机乙发送了3个连续的TCP段,分别包含300字节、400字节和500字节的有效载荷,第3个段的序号为900。若主机乙仅正确接收到第1个和第3个段,则主机乙发送给主机甲的确认序号是( B )
A. 300 B. 500 C. 1200 D. 1400
分析:
在这里插入图片描述
TCP规定只能对按序到达的最高序号进行确认,因此主机乙发送的确认报文段实际上是对第一个数据报文段的确认。由于第一个数据报文段数据载荷的最后一个字节的序号为499,因此针对该序号的确认序号应为500。表明序号499为止的全部数据已经收到了,现在希望接收500号及其后续数据。
7.1 课后练习
- 主机甲和乙建立了TCP连接,主机甲向主机乙发送了两个连续的TCP段,分别包含200字节和300字节的有效载荷,第一个段的序号为100,主机乙正确接收到两个段后,发送给主机甲的确认号是( B )
A. 500 B. 600 C. 800 D. 900
分析: 第一个段100 ~ 299,第二个段300 ~ 599,主机乙正确接收到两个段后,发送给主机甲的确认号是600。
- 主机甲和乙建立了TCP连接,主机甲向主机乙发送了3个连续的TCP段,分别包含200字节、300字节、400字节的有效载荷,第3个段的序号为1000。若主机乙仅正确接收到第1和第3个段,则主机乙发送给主机甲的确认号是( C )
A. 500 B. 600 C. 700 D. 800
分析: 第三个段1000 ~ 1399,第二个段700 ~ 999,第一个段500 ~ 699。
TCP规定只能对按序到达的最高序号进行确认,因此主机乙发送的确认报文段实际上是对第一个数据报文段的确认。由于第一个数据报文段数据载荷的最后一个字节的序号为699,因此针对该序号的确认序号应为700。表明序号699为止的全部数据已经收到了,现在希望接收700号及其后续数据。
因此,若主机乙仅正确接收到第1和第3个段,则主机乙发送给主机甲的确认号是700。
- 主机甲和乙建立了TCP连接,双方持续有数据传输,且数据无差错与丢失。若甲收到1个来自乙的TCP段,该段的序号为1024,确认序号为2048,有效数据载荷为200字节,则甲立即发送给乙的TCP段的序号和确认号分别是( B )
A. 2048、1223 B. 2048、1224 C. 2049、1223 D. 2049、1224
分析: 甲在发送数据之前,明确两个信息:1. 段序号为1024,说明乙发给甲的数据段起始字节序号为1024,有效载荷长度为200,说明该数据段的长度为200,那么甲下次需要的数据段的序号就是1024 + 200 = 1224;2. 乙发给甲的确认序号为2048,说明乙这次需要甲发送的数据段的起始字节序号为2048。获取这两个信息后,甲即可确定要发给乙的序号为2048(从乙的确认序号获知),确认序号为1224(希望下次乙能够发送首字节序号1224 的数据段过来)。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/HUAI_BI_TONG/article/details/118660643
- TCP的连接建立和连接释放
8.1 TCP的连接建立
8.1.1 课后练习
8.2 TCP的连接释放
8.2.1 课后练习
- TCP的连接建立和连接释放
8.1 TCP的连接建立
■ TCP是面向连接的协议,它基于运输连接来传送TCP报文段。
■ TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程。
■ TCP运输连接有以下三个阶段:
⋄ \diamond ⋄ 1. 建立TCP连接
⋄ \diamond ⋄ 2. 数据传送
⋄ \diamond ⋄ 3. 释放TCP连接
在这里插入图片描述
■ TCP的运输连接管理就是使运输连接的建立和释放都能正常地进行。
■ TCP的连接建立要解决以下三个问题:
⋄ \diamond ⋄ 1. 使TCP双方能够确知对方的存在;
⋄ \diamond ⋄ 2. 使TCP双方能够协商一些参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项以及服务质量等);
⋄ \diamond ⋄ 3. 使TCP双方能够对运输实体资源(如缓存大小、连接表中的项目等)进行分配。
■ TCP使用"三报文握手"建立连接
接下来看一下TCP使用三报文握手建立连接的具体过程。如下图是两台要基于TCP进行通信的主机,其中一台主机中的某个应用进程主动发起TCP连接建立,称为TCP客户。另一台主机中被动等待TCP连接建立的应用进程,称为TCP服务器。我们可以将TCP建立连接的过程比喻为"握手","握手"需要在TCP客户和服务器之间交换三个TCP报文段。最初,两端的TCP进程都处于关闭状态。
在这里插入图片描述
一开始,TCP服务器进程首先创建传输控制块,用来存储TCP连接中的一些重要信息,例如TCP连接表、指向发送和接收缓存的指针、指向重传队列的指针、当前发送和接收序号等。之后,就准备接受TCP客户进程的连接请求。此时,TCP服务器进程就进入监听状态,等待TCP客户进程的连接请求。
在这里插入图片描述
TCP服务器进程是被动等待来自TCP客户进程的连接请求,而不是主动发起,因此称为被动打开连接。
在这里插入图片描述
TCP客户进程也是首先创建传输控制块,然后在打算建立TCP连接时向TCP服务器进程发送TCP连接请求报文段,并进入同步已发送状态。TCP连接请求报文段首部中的同步位SYN被设置为1,表明这是一个TCP连接请求报文段。序号字段seq被设置了一个初始值x作为TCP客户进程所选择的初始序号。请注意,TCP规定SYN被设置为1的报文段不能携带数据,但要消耗掉一个序号。
由于TCP连接建立是由TCP客户进程主动发起的,因此称为主动打开连接。
在这里插入图片描述
TCP服务器进程收到TCP连接请求报文段后,如果同意建立连接,则向TCP客户进程发送TCP连接请求确认报文段,并进入同步已接收状态。该报文段首部中的同步位SYN和确认位ACK都设置为1,表明这是一个TCP连接请求确认报文段。序号字段seq被设置了一个初始值y作为TCP服务器进程所选择的初始序号。确认号字段ack的值被设置成了x+1,这是对TCP客户进程所选择的初始序号的确认。请注意,这个报文段也不能携带数据,因为它是SYN被设置为1的报文段,但同样要消耗掉一个序号。
在这里插入图片描述
TCP客户进程收到TCP连接请求确认报文段后,还要向TCP服务器进程发送一个普通的TCP确认报文段,并进入连接已建立状态。该报文段首部中的确认位ACK被设置为1,表明这是一个普通的TCP确认报文段。序号字段seq被设置为x+1,这是因为TCP客户进程发送的第一个TCP报文段的序号为x,并且不携带数据,因此第二个报文段的序号为x+1。请注意,TCP规定普通的TCP确认报文段可以携带数据,但如果不携带数据,则不消耗序号。在这种情况下,所发送的下一个数据报文段的序号仍是x+1,确认号字段ack被设置为y+1,这是对TCP服务器进程所选择的初始序号的确认。
在这里插入图片描述
TCP服务器进程收到该确认报文段后,也进入连接已建立状态。现在,TCP双方都进入了连接已建立状态。它们可以基于已建立好的TCP连接,进行可靠的数据传输。
在这里插入图片描述
思考: 为什么TCP客户进程最后还要发送一个普通的TCP确认报文段呢?这是否多余呢?换句话说能否使用两报文握手建立连接呢?
答案是并不多余,不能简化为两报文握手。
举例说明,考虑这样一种情况:TCP客户进程发出一个TCP连接请求报文段,但该报文段在某些网络结点长时间滞留了,这必然会造成该报文段的超时重传。假设重传的报文段被TCP服务器进程正常接收,TCP服务器进程给TCP客户进程发送一个TCP连接请求确认报文段,并进入连接已建立状态。请注意,由于我们改为"两报文握手",因此TCP服务器进程发送完TCP连接请求确认报文段后,进入的是连接已建立状态,而不像"三报文握手"那样进入同步已接收状态,并等待TCP客户进程发来针对TCP连接请求确认报文段的普通确认报文段。TCP客户进程收到TCP连接请求确认报文段后,进入TCP连接已建立状态,但不会给TCP服务器进程发送针对该报文段的普通确认报文段。现在,TCP双方都处于连接已建立状态,它们可以相互传输数据。之后,可以通过"四报文挥手"来释放连接,TCP双方都进入了关闭状态。一段时间后,之前滞留在网络中的那个失效的TCP连接请求报文段到达了TCP服务器进程,TCP服务器进程会误认为这是TCP客户进程又发起了一个新的TCP连接请求,于是给TCP客户进程发送TCP连接请求确认报文段,并进入连接已建立状态,该报文段到达TCP客户进程。由于TCP客户进程并没有发起新的TCP连接请求,并且处于关闭状态,因此不会理会该报文段。但TCP服务器进程已进入了连接已建立状态,它认为新的TCP连接已建立好了,并一直等待TCP客户进程发来数据,这将白白浪费TCP服务器进程所在主机的很多资源。
综上所述采用三报文手而不是两报文握手来建立TCP连接,是为了防止已失效的连接请求报文段突然又传送到了TCP服务器进程,因而导致错误。
在这里插入图片描述
例: 主机甲向主机乙发送一个(SYN=1,seq=11220)的TCP段,期望与主机乙建立TCP连接,若主机乙接受该连接请求,则主机乙向主机甲发送的正确的TCP段可能是( C )
A. (SYN=0 ,ACK=o0, seq=11221, ack=11221)
B. (SYN=1 ,ACK=1, seq=11220, ack=11220)
C. (SYN=1,ACK=1, seq=11221, ack=11221)
D. (SYN=0 , ACK=o, seq=11220, ack=11220)
分析:
在这里插入图片描述
所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:
在这里插入图片描述
第一次握手 SYN=1,ACK=0: Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
第二次握手 SYN=1,ACK=1: Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
第三次握手 SYN=0,ACK=1 : Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
SYN攻击: 在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产时间占用未连接队列,导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。
8.1.1 课后练习
- TCP采用三报文握手建立连接,其中第一个报文首部中的同步标志位SYN和确认标志位ACK的取值分别是( C )
A. 0,0 B. 0,1 C. 1,0 D. 1,1
分析: TCP采用三报文握手建立连接,其中第一个报文首部中的同步标志位SYN和确认标志位ACK的取值分别是1,0。
- TCP采用三报文握手建立连接,其中第二个报文首部中的同步标志位SYN和确认标志位ACK的取值分别是( D )
A. 0,0 B. 0,1 C. 1,0 D. 1,1
分析: TCP采用三报文握手建立连接,其中第二个报文首部中的同步标志位SYN和确认标志位ACK的取值分别是1,1。
- TCP采用三报文握手建立连接,其中第三个报文是
( C )
A. TCP连接请求 B. 对TCP连接请求的确认 C. 对TCP连接请求确认的确认 D. TCP普通数据
分析: TCP采用三报文握手建立连接,其中第三个报文是对TCP连接请求确认的确认。
- 主机甲向主机乙发送一个(SYN=1, seq=100)的TCP段,期望与主机乙建立TCP连接,若主机乙接受该连接请求,则主机乙向主机甲发送的正确的TCP段可能是( D )
A. (SYN=0, ACK=0, seq=101, ack=101)
B. (SYN=1, ACK=1, seq=100, ack=100)
C. (SYN=0, ACK=0, seq=123, ack=123)
D. (SYN=1, ACK=1, seq=123, ack=101)
分析: 主机甲向主机乙发送一个(SYN=1, seq=100)的TCP段,期望与主机乙建立TCP连接,若主机乙接受该连接请求,则主机乙向主机甲发送的正确的TCP段可能是,SYN=1,ack=101。
- 主机甲发起与主机乙的TCP连接,主机甲选择的初始序号为200,如果三报文握手建立连接过程中最后一个报文不携带数据载荷,则TCP连接建立成功后主机甲给主机乙发送的第一个数据报文段的序号为( C )
A. 199 B. 200 C. 201 D. 202
分析: 主机甲发起与主机乙的TCP连接,主机甲选择的初始序号为200,如果三报文握手建立连接过程中最后一个报文不携带数据载荷,则TCP连接建立成功后主机甲给主机乙发送的第一个数据报文段的序号为201。
8.2 TCP的连接释放
■ TCP通过"四报文挥手"来释放连接
接下来举例说明数据传输结束后,TCP通信双方都可以释放连接。现在,TCP客户进程和TCP服务器进程都处于连接已建立状态。
假设使用TCP客户进程的应用进程通知其主动关闭TCP连接,TCP客户进程会发送TCP连接释放报文段,并进入终止等待1状态。该报文段首部中的终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段。同时,也对之前收到的报文段进行确认。序号seq字段的值设置为u,它等于TCP客户进程之前已传送过的、数据的最后一个字节的序号加1。请注意,TCP规定终止位FIN等于1的报文段即使不携带数据也要消耗掉一个序号。确认号ack字段的值设置为v,它等于TCP客户进程之前已收到的、数据的最后一个字节的序号加1。
TCP服务器进程收到TCP连接释放报文段后,会发送一个普通的TCP确认报文段并进入关闭等待状态。该报文段首部中的确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段。序号seq字段的值设置为v,它等于TCP服务器进程之前已传送过的、数据的最后一个字节的序号加1,这也与之前收到的TCP连接释放报文段中的确认号匹配。确认号ack字段的值设置为u+1,这是对TCP连接释放报文段的确认。
TCP服务器进程这时应通知高层应用进程,TCP客户进程要断开与自己的TCP连接。此时从TCP客户进程到TCP服务器进程这个方向的连接就释放了,这时的TCP连接属于半关闭状态,也就是TCP客户进程已经没有数据要发送了。但TCP服务器进程如果还有数据要发送,TCP客户进程仍要接收,也就是说从TCP服务器进程到TCP客户进程这个方向的连接并未关闭,这个状态可能会持续一段时间。
在这里插入图片描述
TCP客户进程收到TCP确认报文段后就进入终止等待2状态,等待TCP服务器进程发出的TCP连接释放报文段。若使用TCP服务器进程的应用进程已经没有数据要发送了,应用进程就通知其TCP服务器进程释放连接。由于TCP连接释放是由TCP客户进程主动发起的,因此TCP服务器进程对TCP连接的释放称为被动关闭连接。
TCP服务器进程发送TCP连接释放报文段并进入最后确认状态,该报文段首部中的终止位FIN和确认位ACK的值都被设置为1,表明这是一个TCP连接释放报文段,同时也对之前收到的报文段进行确认。现在假定序号seq字段的值为w,这是因为在半关闭状态下TCP服务器进程可能又发送了一些数据。确认号ack字段的值为u+1,这是对之前收到的TCP连接释放报文段的重复确认。
TCP客户进程收到TCP连接释放报文段后,必须针对该报文段发送普通的TCP确认报文段,之后进入时间等待状态。该报文段首部中的确认位ACK的值被设置为1,表明这是一个普通的TCP确认报文段。序号seq字段的值设置为u+1,这是因为TCP客户进程之前发送的TCP连接释放报文段虽然不携带数据,但要消耗掉一个序号。确认号ack字段的值设置为w+1,这是对所收到的TCP连接释放报文段的确认。
TCP服务器进程收到该报文段号就进入关闭状态,而TCP客户进程还要经过两倍的MSL后才能进入关闭状态。MSL的意思是最长报文段寿,RFC793建议2分钟。
在这里插入图片描述
也就是说,TCP客户进程进入时间等待状态后,还要经过4分钟才能进入关闭状态。这完全是从工程上来考虑的,对于现在的网络,MSL取为2分钟可能太长了,因此TCP允许不同的实现,可根据具体情况使用更小的MSL值。
那么TCP客户进程在发送完最后一个确认报文段后,为什么不直接进入关闭状态,而是要进入时间等待状态,2MSL后才进入关闭状态?这是否有必要呢?
来看这种情况,TCP服务器进程发送TCP连接释放报文段后进入最后确认状态,TCP客户进程收到该报文段后发送普通的TCP确认报文段,并进入关闭状态,而不是时间等待状态。然而该TCP确认报文段丢失了,这必然会造成TCP服务器进程对之前所发送的TCP连接释放报文段的超时重传,并仍处于最后确认状态。重传的TCP连接释放报文段到达TCP客户进程,由于TCP客户进程属于关闭状态,因此不理睬该报文段。这必然会造成TCP服务器进程反复重传,TCP连接释放报文段并一直处于最后确认状态,而无法进入关闭状态。因此,时间等待状态以及处于该状态2MSL的时长可以确保TCP服务器进程可以收到最后一个TCP确认报文段,而进入关闭状态。另外,TCP客户进程在发送完最后一个TCP确认报文段后,再经过2MSL时长,就可以使本次连接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的TCP连接中不会出现旧连接中的报文段。
在这里插入图片描述
以上就是TCP通过"四报文挥手"释放连接的过程。
■ TCP中保活计时器的作用。
设想这样一种情况:TCP双方已经建立了连接,后来TCP客户进程所在的主机突然出现了故障。显然,TCP服务器进程以后就不能再收到TCP客户进程发来的数据。因此,应当有措施使TCP服务器进程不要再白白等待下去,换句话说,TCP服务器进程应该如何发现这种情况呢?
在这里插入图片描述
方法就是使用饱和计时器。TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动饱和计时器。若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后每隔75秒钟发送一次。若一连发送10个探测报文段后仍无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出了故障,接着就关闭这个连接。
■ TCP服务器进程每收到一次TCP客户进程的数据,就重新设置并启动保活计时器(2小时定时)。
■ 若保活计时器定时周期内未收到TCP客户进程发来的数据,则当保活计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后则每隔75秒钟发送一次。若一连发送10个探测报文段后仍无TCP客户进程的响应,TCP服务器进程就认为TCP客户进程所在主机出了故障,接着就关闭这个连接。
8.2.1 课后练习
- TCP的通信双方,有一方发送了FIN标志位为1的报文段,表示( B )
A. 将断开通信双方的TCP连接
B. 单方面释放连接,表示本方已经无数据发送,但可以接收对方的数据
C. 中止数据发送,双方都不能发送数据
D. 连接被重新建立
分析: TCP的通信双方,有一方发送了FIN标志位为1的报文段,表示单方面释放连接,表示本方已经无数据发送,但可以接收对方的数据。
- 假设TCP客户与TCP服务器的通信已经结束,TCP客户与TCP服务器之间端到端的平均往返时间为RTT,在t时刻TCP客户请求断开连接,则从t时刻起,TCP服务器释放该连接的最短时间是( C )
A. 0.5个RTT
B. 1个RTT
C. 1.5个RTT
D. 2个RTT
分析: 假设TCP客户与TCP服务器的通信已经结束,TCP客户与TCP服务器之间端到端的平均往返时间为RTT,在t时刻TCP客户请求断开连接,则从t时刻起,TCP服务器释放该连接的最短时间是1.5个RTT。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/HUAI_BI_TONG/article/details/118672369
- TCP报文段的首部格式
9.1 课后练习
- TCP报文段的首部格式
■ 为了实现可靠传输,TCP采用了面向字节流的方式。
■ 但TCP在发送数据时,是从发送缓存取出一部分或全部字节并给其添加一个首部使之成为TCP报文段后进行发送。
⋄ \diamond ⋄ 一个TCP报文段由首部和数据载荷两部分构成;
⋄ \diamond ⋄ TCP的全部功能都体现在它首部中各字段的作用。
在这里插入图片描述
■ TCP报文段的首部格式:
在这里插入图片描述
源端口: 占16比特,写入源端口号,用来标识发送该TCP报文段的应用进程。
目的端口: 占16比特,写入目的端口号,用来标识接收该TCP报文段的应用进程。
在这里插入图片描述
序号: 占32比特,取值范围[0, 2 32 ^{32} 32-1],序号增加到最后一个后,下一个序号就又回到0。
指出本TCP报文段数据载荷的第一个字节的序号。
在这里插入图片描述
确认号: 占32比特,取值范围[0, 2 32 ^{32} 32-1],确认号增加到最后一个后,下一个确认号就又回到0。
指出期望收到对方下一个TCP报文段的数据载荷的第一个字节的序号,同时也是对之前收到的所有数据的确认。
若确认号=n,则表明到序号n-1为止的所有数据都已正确接收,期望接收序号为n的数据。
确认标志位ACK: 取值为1时确认号字段才有效;取值为0时确认号字段无效。
TCP规定,在连接建立后所有传送的TCP报文段都必须把ACK置1。
数据偏移: 占4比特,并以4字节为单位。
用来指出TCP报文段的数据载荷部分的起始处距离TCP报文段的起始处有多远。这个字段实际上是指出了TCP报文段的首部长度。
首部固定长度为20字节,因此数据偏移字段的最小值为(0101) 2 _2 2。
首部最大长度为60字节,因此数据偏移字段的最大值为(1111) 2 _2 2。
保留: 占6比特,保留为今后使用,但目前应置为0。
窗口: 占16比特,以字节为单位。指出发送本报文段的一方的接收窗口。
窗口值作为接收方让发送方设置其发送窗口的依据。
这是以接收方的接收能力来控制发送方的发送能力,称为流量控制。
校验和: 占16比特,检查范围包括TCP报文段的首部和数据载荷两部分。
在计算校验和时,要在TCP报文段的前面加上12字节的伪首部。
同步标志位SYN: 在TCP连接建立时用来同步序号。
在这里插入图片描述
终止标志位FIN: 用来释放TCP连接。
在这里插入图片描述
复位标志位RST: 用来复位TCP连接。
当RST=1时,表明TCP连接出现了异常,必须释放连接,然后再重新建立连接。
RST置1还用来拒绝一个非法的报文段或拒绝打开一个TCP连接。
推送标志位PSH: 接收方的TCP收到该标志位为1的报文段会尽快上交应用进程,而不必等到接收缓存都填满后再向上交付。
紧急标志位URG: 取值为1时紧急指针字段有效;取值为0时紧急指针字段无效。
紧急指针: 占16比特,以字节为单位,用来指明紧急数据的长度。
当发送方有紧急数据时,可将紧急数据插队到发送缓存的最前面,并立刻封装到一个TCP报文段中进行发送。紧急指针会指出本报文段数据载荷部分包含了多长的紧急数据,紧急数据之后是普通数据。
最大报文段长度MSS选项: TCP报文段数据载荷部分的最大长度。
窗口扩大选项: 为了扩大窗口(提高吞吐率)。
时间戳选项: 用来计算往返时间RTT。
用于处理序号超范围的情况,又称为防止序号绕回PAWS。
选择确认选项: 用来实现选择确认功能。
填充: 由于选项的长度可变,因此使用填充来确保报文段首部能被4整除(因为数据偏移字段,也就是首部长度字段,是以4字节为单位的)。
9.1 课后练习
- TCP报文段首部的最小长度为( A )
A. 20字节 B. 40字节 C. 60字节 D. 80字节
分析: TCP报文段首部的最小长度为20字节。
- TCP报文段首部的最大长度为( C )
A. 20字节 B. 40字节 C. 60字节 D. 80字节
分析: TCP报文段首部的最大长度为60字节。
- TCP报文段首部中序号字段的作用是( B )
A. 指明TCP报文段首部第一个字节的序号
B. 指明TCP报文段的数据载荷的第一个字节的序号
C. 指明TCP报文段的数据载荷的最后一个字节的序号
D. 指明TCP报文段的数据载荷的长度
分析: TCP报文段首部中序号字段的作用是指明TCP报文段的数据载荷的第一个字节的序号。
- TCP报文段首部中窗口字段的值( C )
A. 指明自己的拥塞窗口的尺寸
B. 指明对方的发送窗口的尺寸
C. 指明自己的接收窗口的尺寸
D. 指明对方的拥塞窗口的尺寸
分析: TCP报文段首部中窗口字段的值指明自己的接收窗口的尺寸。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/HUAI_BI_TONG/article/details/118684397