文章目录
- [第五章 运输层](#第五章 运输层)
第五章 运输层
一、运输层概述
1.传输层的功能
- 运输层提供进程之间的逻辑通信,也就是所谓的端到端通信,依靠套接字Socket(主机IP+端口号)来精准定位进程
- 对收到的报文进行差错检测
- 复用和分用
- 复用:发送方不同的应用进程可以使用相同的传输层协议
- 分用:接收方在收到报文段读取其首部以后可以将报文发送到正确的进程
- 对复用分用的理解:在同一个片区的快递可以由一个快递小哥揽收(对应发送方使用相同的传输层协议),在收到货以后,收货地的快递小哥能将快递准确送到快递单上面写的地址(对应接收方读取报文信息以后能将报文准确送达)
2.各层次传输单元的归纳对比
- 物理层:比特流
- 数据链路层:数据帧
- 网络层:数据报
- 传输层:报文段
- 注意事项:传输层是只有主机才有的层次,主要是实现端到端的通信,而数据传输过程中途径的网络设备最多只有到网络层
3.两个主要协议的概述(TCP&UDP)
-
无连接的UDP用户数据报协议
使用UDP用户数据报,不需要提前建立连接(意思是当目的主机收到UDP报文以后不需要给出任何的确认),不提供可靠交付,但进行广播或多播。使用此协议的时候,此时的逻辑通信信道是不可靠的
-
面向连接的TCP传输控制协议
使用TCP报文段,需要提前建立连接,提供可靠的交付,不提供广播或多播服务。使用此协议的时候,此时的逻辑通信信道相当于可靠的半双工信道
-
TCP/IP体系的运输层协议
-
常见的应用和应用层协议所使用的运输层协议
4.端口的概念及理解
- 理解:就好比两个人要互通书信,首先要知道对方这个人在哪,其次要知道人家叫什么。人可以理解为是一个应用进程,地址可以对应IP地址,人的名字就是应用进程的端口号了。端口号就是用来标识一个应用进程的
- 定位应用进程要靠IP地址和端口号共同实现,这两者加起来有一个共同名称------套接字Socket
- 端口号长度为16位,分为以下两大类
-
服务器端使用的端口号
-
熟知端口号/全球通用端口号:熟知端口号一般被指派给TCP/IP体系中重要的应用进程,常见的有
-
登记端口号:为没有熟知端口号的应用进程准备的
-
-
客户端使用的端口号/临时端口号/短暂端口号
这类端口号仅仅在进程运行时才进行动态选择,进程结束了以后就不用了,是给进程临时使用的。
-
二、UDP数据报协议概述(知道特点以及和TCP的区别即可,非重点)
1.UDP特点
UDP用户数据报只是在IP数据报服务的基础上添加了复用分用功能和差错检测功能,主要特点如下:
-
UDP是无连接的
-
UDP采用的是尽最大努力交付,即不保证可靠交付
-
UDP是面向报文的
-
UDP没有拥塞控制
-
UDP支持一对一、一对多、多对一、多对多的交互通信。也就是支持多播和广播。
-
首部只有8个字节,比TCP的20字节首部要短
2.UDP首部格式
UDP的首部由四个字段组成,每个字段占2字节
-
源端口号:仅在需要对方回信的时候使用,不需要是可全0
-
目的端口号
-
UDP用户数据报长度(最小值为8,即仅有首部的时候)
-
检验和:用于检验是否有差错
3.UDP的校验方式
- UDP在校验的时候会加上12字节的伪首部,伪首部仅仅用于计算校验和。
- UDP计算检验和的方式和IP数据报类似,但是不同的是IP数据报仅仅对数据报首部进行检验,而UDP则是将首部和数据部分一起都检验。
三、传输控制协议TCP概述【重点了解】
1.TCP的特点(要和UDP区别开来)
- 面向连接
- 保证可靠交付
- 全双工通信
- 面向字节流
2.TCP的连接(套接字Socket)
TCP协议把连接作为最基本的抽象,每一条TCP抽象连接都能被一对套接字对唯一确定。具体建立连接的过程后面展开
套接字Socket=(IP地址 : 端口号)
3.TCP报文段的首部格式
4.TCP报文的常见首部标志字段
- 紧急URG:当标志字段(flag)的URG=1时,表示紧急指针字段有效,表明此数据包中有紧急数据,应该尽快传送。
- 确认ACK:当且仅当ACK=1时,确认号字段才是有效的,反之无效。TCP规定,在连接建立以后所有传送的报文的ACK必须为置为1。
- 推送PSH:当两个应用进程进行交互式通信时,将PSH设置为1使得报文在被接收方接收以后尽快推送并交付给应用进程,不再等到缓存填满以后再向上交付。
- 复位RST:当RST=1时,表明TCP链接中出现严重差错,此时必须释放后重新建立连接。
- 同步SYN:用来在建立连接时同步序列号,当SYN=1,ACK=0时表示这是一个请求建立连接的报文;当SYN=1,ACK=1时,表示接收方同意建立连接。
- 终止FIN:表示停止、终止TCP链接,当FIN=1时表明此报文段的发送方已经完成数据的发送,申请释放TCP连接
5.其他常用首部字段
- 序号(seq):TCP协议是面向字节流的,也就是每一个字节都需要按顺序编号。序号占4字节,也就是最大值为2^32。序号也称作报文段序号,表示的是本报文段数据部分的第一个字节的序号。
- 确认号(ack):4字节,表示期待收到对方下一个报文段的第一个数据字节的序号。也就是期待对方下一次从哪个序号的数据开始发送,一般确认号是用来控制滑动窗口的,经常会用到。需要注意的是,只有当标志字段中的ACK位设置为1时,确认号才生效。若确认号为N,则表示N以前的数据全都收到,不包括N。
- 数据偏移:表示的是TCP报文段中数据部分距离报文段起始位置有多远(就是用来告诉系统从哪里开始是报文段的数据部分)。占4位,注意是4位,4个二进制位,不是4字节,最大能够表示的十进制数为15。又由于数据偏移字段计量单位是32位(4字节),所以数据偏移量最大是15x4=60字节,这也是TCP首部的最大长度(即选项长度不可以超过40字节,固定长度已经占20字节了)。
- 窗口:占2字节。这就决定了窗口值的取值范围是0~2^16。窗口值用来告诉对方自己能接收多少数据,也就是表示接收窗口的大小,也是允许发送方发送数据量的最大值。接收方的给的窗口值是发送方设置发送窗口的依据。
四、TCP连接的过程(三次握手与四次挥手)【重重重点】
1.TCP连接的建立------三次握手
TCP的连接建立需要经历三次握手:第一次握手是由客户端发出,将SYN标志置1,申请与服务器端建立连接,仿佛是说"你好,聊天吗";
服务器端收到请求以后确认与其建立连接,回复一个确认数据包,SYN和ACK标志置1,这是第二次握手,仿佛是回复"可以,你说吧";
客户端收到来自服务器端的确认以后,对其确认再进行一次确认,将ACK标志置1,表示确认,仿佛是说"收到,那我开始说了",至此完成第三次握手,TCP链接正式建立,客户端会向上层汇报,开始数据传送。
2.TCP连接的释放------四次挥手
TCP链接的释放需要经历四次挥手:第一次挥手一般由最开始发起连接的一方(一般是客户端)主动提出,将FIN标志置1,表示提出终止连接的申请,部分数据包可能也会将ACK标志置1,可以理解为对之前所接受的数据进行确认,这是第一次挥手,仿佛是在跟服务器端说"我要挂了,你还有事吗";
在收到客户端的终止TCP连接申请以后,服务器端会将ACK标志置1发还客户端,表示对申请的确认,这是第二次挥手,仿佛是在回复"已经收到申请,你先别急,我再想想还有没有事,等一下再通知你";
完成第二次挥手以后,服务器端会向上汇报,通知应用进程停止接受数据,并确认是否还有尚未发送完成的数据,若无,则将FIN和ACK标志置1,发还给客户端,申请释放连接,这是第三次挥手,仿佛是在说"我这边没事了,你可以挂了";
客户端收到第三次挥手的数据包以后会发送对这个数据包的确认数据包,将ACK置1,表示确认断开连接,此时TCP连接将进入预关闭状态,客户端将设置一个时间等待计时器(TIME-WAIT timer)并等待2MSL时间确保服务器端彻底挂掉,防止"诈尸",若过了2MSL时间以后服务器端没有任何数据包发送过来,客户端就能彻底确认服务器端已经正常释放连接,自己也就会随之释放连接,至此,四次挥手结束,TCP连接彻底被释放。
五、可靠传输原理及TCP可靠传输的实现
理想的传输条件满足:传输信道不产生差错;不管发送方以多快的速度发送数据,接收方总能来得及处理接收到的数据。
1.停止等待协议
全双工通信的双方即是接收方也是发送方,假设现在只有A发送数据,而B作为接收方。
停止等待协议就是每发送完一个数据分组,就要等待对方的确认,在收到对方的确认以后再发送下一个分组
-
无差错的时候
-
出现差错------超时重传
每个分组都会进行编号,并且在每一个分组收到确认之前都会先保留该分组的一个副本,发出分组以后会设置一个超时重传计时器,当计时器到期之前收到了确认,则撤销,反之则进行超时重传。超时计时器的设置应该略大于平均往返时延RTT
-
确认丢失和确认迟到
确认报文丢失,发送方则会重新发送一个新的数据报文,接收方丢弃掉之前接收到的,收下最新发送的。确认报文迟到,接收方在收到重传的数据报后丢弃也是要丢弃掉最开始收到的,然后对重传的数据包再发送一次确认,当发送方收到之前迟到的报文以后就收下,但是不做其他操作。
-
信道利用率
停止等待协议的缺点是信道利用率太低。
2.连续ARQ协议
连续ARQ协议又叫滑动窗口协议。在窗口内的分组可以连续发出,而不用一个发完等确认再发下一个,发送方每收到一个确认,窗口就往前滑动一格。接收方一般采用累积确认的方式,只需要对按序到达的最后一个分组进行确认,这就表示在这个分组之前的其他分组已经收到了。
-
以字节为单位的滑动窗口
- TCP的滑动窗口是以字节为单位的
- 发送方的发送窗口不能比接收方的接收窗口大,不然接收方会出现接收不过来的情况
- 发送窗口左边沿后面(后沿)的数据表示已发送且收到确认;发送窗口右边沿前面(前沿)的数据表示不允许发送(也就是还没轮到他);前后沿中间的数据表示允许发送的数据。
- 滑动窗口有两种状态:前移和静止不动。滑动窗口不可能出现向后移动,即回退撤销确认的情况。但滑动窗口可能会收缩,TCP标准不赞成这样。
-
滑动窗口需要3个指针来描述,具体的发送接收确认过程如下
- P1和P3指针之间表示A的发送窗口
- P1和P2指针之间表示已发送但是未收到确认的数据
- P2和P3指针之间表示允许发送但尚未发送的数据,这部分也称为有效窗口/可用窗口
现在A已发送11字节的数据,但尚未被确认。有效窗口/可用窗口为20-11=9,即实际总窗口大小减去已发送的。
对于B,接收窗口左侧的数据是已确认并交付到主机的,接收窗口内是允许接收的,接收窗口右侧是不允许被接收的数据。观察上图(5-15)B只收到了32和33这两个数据,是跳过了31的(没有收到,可能是丢失也可能迟到),即未按序收到了32和33。
此时B要向A发送确认号,所谓确认号即B期待收到的数据是哪个,那必然是31。
接收方只对按序到达的序列中的最大值加一进行确认。32和33都收到了,但是他们不是按序到达的,所以这时候要对未按序到达的最小号进行确认。
所以此时B的确认号仍然是31,这是他期待收到的,A收到了以后会重新从31开始发送。
上图中,对于B,此时已按序收到了31~33的数据,对按序到达的序列中最大值进行确认,给出的确认号是34。表示34以前的数据都已经收到了,现在期待你发送的数据序号是34号。
而A在收到34的确认号以后,P1指针移动到接收方所期待的数据号34,P3指针相应往前移,整个滑动窗口就实现了前移。
-
发送缓存和接收缓存
- 发送缓存
发送缓存用于存放准备发送的数据和已发送但未确认的数据 - 接收缓存
接收缓存用于存放按序到达但未被应用进程读取的数据和未按序到达的数据
- 发送缓存
六、TCP的流量控制
1.基于滑动窗口的流量控制
-
流量控制就是让发送方的发送速率不要过快,要让发送方来得及接收数据
-
再次强调,滑动窗口的度量单位是字节,不是报文段
-
只有当报文首部中ACK设置为1,确认号才是生效的
-
rwnd:receiver window接收方窗口,表示允许发送方发送的未收到确认的最大数据总量
-
ACK和ack:ACK是标志字段中的确认位,ack是确认号具体值。当ACK=1时,ack才有效。
2.TCP死锁与死锁的解决方案
- 死锁:两个或两个以上的进程互相等待彼此的信息/资源,类似于情侣冷战。比如B向A发送了零窗口报文告诉A不要再给他发消息了,但是不久以后B发现自己还能接收A的数据,于是设置自己的rwnd=400并发送给A,但是这个报文丢失了------于是,A就一直在等待B的非零窗口报文,B则以为自己已经告诉A能够发消息了,一直在等A的数据,这样两个人就形成了一种互相等待的局面,即死锁。
- 死锁的解决方法:TCP为每一个连接设置了持续计时器(这个跟四次挥手的那个计时器不是一个东西),只要有一方收到了零窗口报文,则启动计时器,如果计时器到期了就发送一个携带有1字节数据的零窗口探测报文段。接收方收到零窗口探测报文段以后,要对其进行确认,给出现在的窗口值,如果给出的窗口值仍然是0,那么发送探测报文段的一方就重置计时器,如果给出的窗口值不是0,那么发送探测报文段的一方收到了以后就可以开始发送数据了。
3.TCP的传输效率控制
- TCP报文段发送时机的控制
当应用进程把数据送到TCP的发送缓存以后,剩下的发送任务就交由TCP来实现,为了实现流量控制,我们需要利用某些机制来控制TCP发送报文段的时机- TCP维持一个变量,令其等于最大报文段长度MSS。当缓存中的数据达到MSS的时候,就组装成一个TCP报文段发送过去
- 由发送方指明的Push操作。当报文段首部标志字段的PUSH位设置为1时,就无需等待缓存满,直接会发送并提交给应用进程。
- 在缓存中的数据还没有达到MSS的时候,发送方设置的计时器到期了,现在不管有多少数据就都组成一个报文段发出去。
- Nagle算法
在TCP的实现中广泛使用了Nagle算法,能有效提高网络吞吐量。大致实现如下:
发送方先把要发送的数据的第一个字节发出去,将后续到达的数据放入缓存,在收到了对这第一个字节数据的确认以后再把缓存中的数据组成一个报文段发出去。另外,当达到发送窗口大小的一半或者已经达到最大报文段长度MSS的时候,立即组装一个报文段发出。 - 糊涂窗口综合征
大概就是说如果再接收方的接收窗口很小,比如只有1字节的时候,就不要让发送方发送数据了,你发一个确认报文都至少20字节了,结果告诉人家发送方说你现在窗口只有1字节,你这不是扯犊子吗,这样很浪费资源,降低网络效率。
解决方法:接收方等待一段时间,使得至少缓存能装的下一个最大报文段长度,或者等到缓存已有一半的空闲空间的时候,再向发送方发送确认报文,并告知当前窗口值。此外,发送方也不应该发送太小的报文段,而是应该将数据累计成足够大的报文段再发出。
七、TCP的拥塞控制【重点】
1.拥塞与拥塞控制【了解】
-
拥塞的定义
- 某一段时间中,网络中对某一资源的需求量大于该资源所能提供的可用部分,就会造成拥塞。总需求大于供给。
- 拥塞导致的重传会更加加剧拥塞
- 许多资源都呈现供应上的不足时,整个网络的吞吐量将随输入负荷的增大而下降
-
拥塞控制的基本原理
- 拥塞控制指的是防止过多的数据注入到网络中,以免路由器或者链路过载超负荷。拥塞控制执行的大前提是,现有的网络能够承受现有的负荷。
- 拥塞控制是宏观调控,流量控制是端到端的通信量控制。
- 如果不进行拥塞控制,当链路中的资源增加到一定量的时候,就会出现很多进程互相等待资源的情况,即发生死锁。具体一点讲,有点像高速公路上的堵车------高速公路的堵车有时候并不是完全不动,而是由于车辆太多,且前面部分车辆移动太慢,进而就会导致一整条车队跟静止一样,甚至严重到车队的最尾部是基本上停下来了。
-
拥塞控制的两种方法
- 开环控制:在设计网络的时候就把拥塞的可能考虑进来,力求网络在工作的时候不会产生拥塞
- 闭环控制:闭环是基于反馈环路的概念,主要是一个监控拥塞、传递拥塞发生的信息、调整网络的运行以解决拥塞的过程。
2.TCP的拥塞控制算法【重点】
- TCP的四种拥塞控制算法
TCP的拥塞控制是也是基于窗口实现的,发送方会维持一个叫做拥塞窗口的状态变量,并使自己的发送窗口等于拥塞窗口。拥塞窗口的大小取决于网络状态并且是动态变化的。拥塞窗口记作cwnd(congestion window),度量单位一般是以报文段而不是字节。- 慢开始:慢开始不是指窗口变化速度很慢,而是指一开始以较小的窗口(通常是1个报文段)开始传输,但他的增长速度是很快的,是以2为底的指数型增长,也就是说每经过一次往返时延RTT,拥塞窗口都会在上一次的基础上乘以2加倍。
- 拥塞避免:拥塞窗口cwnd以线性增长,每次增加1。目的是让拥塞窗口增长得缓慢一点,以免网络出现拥塞。
- 快重传:快重传要求接收方要立即确认,如果收到了失序的报文段,要立即对已收到的报文段发出连续3个确认。而发送方一旦收到3个连续的对某个报文(比如M2)的确认,立即重传该重复确认的报文序号的下一个(M3)
- 快恢复:如果收到了3个连续的对某个报文的确认,则说明只丢失了某个别的报文,使用快恢复。设置门限值为拥塞窗口的一半,并让新的拥塞窗口等于门限值。
- 慢开始和拥塞避免【重点】
- 基于慢开始门限(ssthresh)的拥塞控制过程
- 当cwnd小于门限值,使用以2为底的指数增长的慢开始算法
- 当cwnd大于或等于门限值,停止使用慢开始算法,转而采用拥塞避免算法,使cwnd线性增长
- 门限值要发生调整的情况
- 当发生超时,设置慢开始门限值为当前用拥塞窗口的一半,即ssthresh=cwnd/2,并令cwnd=1,重新执行慢开始算法
- 当出现三个重复的ACK(发生了快重传)时,要使用快恢复算法,设置ssthresh=cwnd/2,并直接令cwnd=ssthresh,后执行拥塞避免算法。
- 发送方窗口的上限值=Min[rwnd,cwnd]。即发送方窗口的上限值取决于接收方窗口和拥塞窗口两者的最小值。
- 例题:设TCP的ssthresh初始值为8(单位为报文段)。当拥塞窗口上升到12时网络发生了超时,TCP使用慢开始和拥塞避免。试分别求出RTT=1到RTT=15的各拥塞窗口的大小,并说明原因。
- 基于慢开始门限(ssthresh)的拥塞控制过程