计网的运输层笔记

本文深入探讨了运输层协议的作用,特别是TCP和UDP的区别。TCP提供面向连接、可靠的数据传输服务,通过三次握手建立连接,采用拥塞控制和流量控制策略确保数据的准确无误传输。UDP则是无连接的,速度快但不可靠,适用于对实时性要求高的应用如DNS。此外,文章还介绍了TCP的连接管理和断开连接的四次挥手过程,以及拥塞控制的慢开始、拥塞避免、快重传和快恢复算法。
摘要由CSDN通过智能技术生成

第三章 运输层

概论和运输层服务

​ 运输层协议为运行在不同主机上的应用程序提供了逻辑通信,从应用程序角度来说,逻辑通信使运行在不同的主机上好像直接相连起来。在发送方,运输层将应用程序的报文转为运输层分组,将报文切割为一段段的报文,并在报文的首部加上对应运输层协议。

运输层和网络层的关系

​ 运输层协议只运行在端系统上,将来自应用程序的数据移动到网络边缘。中间路由器既不处理也不是识别运输层加在应用层的报文任何信息。

运输层概述

​ 将TCP和UDP的分组统称为报文段,而将数据报保留给网络层分组。

​ IP服务模型是尽力而为交付服务,但不确保报文段的交付,不保证报文段的按序交付,也不保证报文段中的数据完整性,所以IP被称为不可靠服务。

多路复用与多路分解

​ 在目的主机,运输层将从网络层接收到的数据报送到对应的应用程序中。进程有多个套接字,接收主机中的运输层通过中间的套接字传递数据,由于在任何主机都有多个套接字,套接字有唯一的标识符来区分。

​ 为了将运输层报文段定向到对应的套接字,在每个运输层的报文段首部设置几个字段。在接收方,运输层检查这些字段并标识出接收套接字,然后将报文段定向到对应的套接字,这个过程称为多路分解。在发送方,从不同的套接字中收集数据块,为每个数据块生成对应的报文段,然后将其送到网络层的工作称为多路复用。

​ 运输层多路复用的要求:套接字有唯一标识符;每个报文段有字段标明要交付的套接字。这些特殊字符就是源端口号字段目的端口号字段。0~1023为周知端口号,受到严格限制。

无连接的多路复用和多路分解

​ 一个UDP套接字是由一个包含目的IP地址和目的端口号全面标识的,如果有两个UDP报文有不同的源IP地址或端口号,但有相同的目的IP地址和目的端口号,那么这两个报文段通过相同的套接字送到相同的应用进程中。

面向连接

​ TCP套接字是由源IP地址,源端口号,目的IP地址,目的端口号来标识的。当不同主机向相同的服务器发起HTTP会话,即使不同主机的端口号相同,服务器会根据主机的IP地址分别分配对应的端口号。

无连接运输:UDP

​ UDP只是将从应用程序得到的数据,附加源端口号和目的端口号,以及一些字段,就直接交付给网络层。网络层封装完报文段后就传输给接收主机。接收主机接收到报文,UDP使用目的端口号交付数据给应用程序。在发送数据前,发送方和接收方的运输层实体没有进行握手。

​ DNS是一个通常使用UDP的应用层协议。当一台主机的DNS应用程序想要进行查询,就构造了一个UDP报文,直接网络层封装发送到域名服务器。查询主机等待结果,如果没有收到响应,要么选择另一台名字服务器,要么告诉调用DNS的应用程序无法得到响应。

​ 选择UDP而不是TCP的原因:

  • 应用层可以控制发送时间和发送数据:TCP有拥塞控制

  • 无需建立连接:TCP需要传输数据前进行三次握手,断开连接时进行四次握手

  • 无维护连接状态:TCP需要维护连接状态,包括接收缓存和发送缓存。

    UDP没有拥塞控制,但实际中网络需要防止加入拥塞状态。当每个用户都以流式高比特率传输数据而无拥塞控制时,会使路由器大量分组溢出,导致搞丢包率。由无控制的UDP发送方引入的高丢包率导致TCP发送方进行拥塞控制,减小速率。UDP缺乏拥塞控制导致高丢包率,并搞垮TCP会话。

UDP报文结构

​ 应用层数据占用了UDP报文段的数据字段。接收使用检验和来检查报文段是否存在差错。

可靠数据传输原理

​ 可靠数据传输服务的抽象是指数据可以通过一条可靠信道进行传输,有可靠信道,就不会有传输数据比特受到损毁或丢失。这就是TCP为调用它的因特网提供的服务。

​ 下图说明数据传输协议的接口。通过rdt_send()函数,可以调用数据传输协议的发送方。将要发送数据交付给接收方的上层。在接收方,当分组从信道的接收端抵达时,将调用rdt_rcv()。当rdt协议想向较高层交付数据时,就调用deliver_data()

在这里插入图片描述

构造可靠数据传输协议

完全可靠信道可靠数据传输:rdt 1.0

​ 首先考虑信道是可靠信道的情况。下图显示rdt 1.0发送方和接收方的有限状态机定义。

​ 引起变化的事件在横线上,事件发生采取的措施在横线下。如果对一个事件没有采取任何动作或没有对应操作,将在横线上或下显示一个^。

在这里插入图片描述

​ rdt的发送方只通过rdt_send(data)从较高层发送数据,产生一个包含该数据的分组(经由make_pkt(data)动作),并将数据报发送到信道。rdt的接收方,通过rdt_rcv(packet)从信道接收分组,从分组取出数据(extract(packet,data)动作),并将数据上传到高层。

具有比特差错信道上的可靠数据传输:rdt 2.0

​ 使用肯定确认(ACK)和否定确认(NAK),基于这种重传机制的可靠数据传输协议称为自动重传协议。

在这里插入图片描述

在这里插入图片描述

​ 上图揭示了rdt 2.0的过程,rdt 2.0的发送方有两个状态。在最开始的状态中,发送方协议等待上层的数,当rdt_send(data)发生时,发送方将产生一个包含发送数据的分组,并计算校验和。发送完分组后,等待接收方的ACK或NAK分组。如果收到ACK,就重回最初状态等待数据;如果是NAK,就重发数据。rdt 2.0的接收方要么回答一个ACK,或者回答一个NAK。

​ 这个协议的问题在于ACK或NAK协议分组是否出缺陷,否则发送方不确定是否要重传数据。处理这个问题的方法,就是在数据分组中添加一新字段,让发送方进行分组编号,即将发送的数据分组的序号放在该字段。

​ 产生了rdt 2.1的FSM图

在这里插入图片描述

在这里插入图片描述

​ 发送方接收到对同一个分组的两个ACK后,知道接收方没有正确接收分组,就重传。

在丢包信道上的可靠数据传输:rdt 3.0

​ 发送方需要等待一个往返时延,才能确定分组丢失了。需要一个倒计数定时器,在一个给定的时间过期后,可中断发送方。

回退N步

​ 在回退N步中,允许发送方发送多个分组而不确认。

​ 下图中说明了GBN协议的序号范围,将基序号定义为最早的未确认分组,可以将序号范围分割为4部分,0base-1都是已发送已确认的分组,basenextseqnum的序号对应已经发送但未确认的分组,nextseqnum~nextseqnum+N-1内的是要发送的数据,大于等于base+N的数据是不可使用的,直到当前的流水线中未被确认分组得到确认为止。

​ 那些已被发送但还未被确认的分组的许可序号范围可以被看成是一个在序号范围长度为N的窗口,随着协议的进行,窗口会向前滑动。

​ GBN发送方必须响应以下三种类型的事件:上层调用:当上层调用send函数时,协议要检查窗口是否已满,如果未满,就发送;如果已满,选择返回或者缓存数据;收到ACK:对序号为n的分组采取累积确认的方式。;超时事件:定时器用于恢复丢失数据或确认分组。

面向连接的运输:TCP

TCP连接

​ TCP是面向连接的,一个应用程序在向另一个应用程序发送数据时,需要建立起连接。TCP提供的是全双工服务,建立起连接的两台主机可以相互发送数据。

TCP和UDP的区别

​ TCP是面向连接的,UDP是无连接的,即发送数据时,不需要建立连接;

​ TCP可靠,UDP不可靠,不可靠是指UDP收到报文后,不需要给出任何确认;

​ TCP只支持点对点的通信,UDP支持一对一,一对多,多对多的通信;

​ TCP是面向字节流的,UDP是面向报文的,面向字节流是指发送数据时以字节为单位,一个数据包可以拆分成若干组进行发送,而UDP一个报文只能一次发完;

​ TCP有拥塞控制,UDP没有;

​ HTTP不可以使用UDP,因为HTTP需要基于可靠的传输协议,而UDP不可靠。

在这里插入图片描述

​ 当建立起连接时,客户机进程向服务器进程发送数据的情况。客户机进程的数据通过套接字进入传输层时,数据就由客户机的TCP控制。TCP将这些数据引导到该连接的发送缓存中,发送缓存是在三次握手初期建立的。接下来TCP会不时从缓存中取出数据,TCP可以取出并放入报文段的数据收到最大报文段长限制。

TCP如何保证传输的可靠

  1. 数据包校验
  2. 对失序数组重排
  3. 丢弃重复数据
  4. 应答机制:接收方收到数据之后,会发送确认
  5. 超时重发:发送方发送出数据后,会设置一个超时计数器,超时未接收到接收方的确认,则重新发送这个数据
  6. 流量控制:确保接收端能够接收发送方而不溢出。

TCP报文段结构

​ 下图是TCP报文段结构

在这里插入图片描述

​ 和UDP一样,首部包含源端口号和目的端口号,还包括32比特序号字段和32比特确认号字段,16比特接收窗口字段,4比特首部长度字段,6比特的标志字段。

​ TCP报文中最重要的是序号和确认号,主机填充进入确认号的是主机期望从另一台主机收到的下一字节的序号,序号字段是此次发送的数据编号。

流量控制

​ 一条TCP连接的双方主机都为该连接设置了接收缓存。当TCP收到对应数据时,将数据放入接收缓存。当接收方没有将缓存的数据取出来而发送方又不断发送数据,会导致数据溢出。

​ 所以TCP为应用程序提供了流量控制服务器以消除缓存溢出问题,就是将发送方的发送速率和接收方的读速率相匹配。

​ TCP通过让发送方维护一个接收窗口的变量来提供流量控制,接收窗口告诉发送方接收方还有多少缓存,TCP是全双工的,所以接收方和发送方都维护了一个接收窗口。

在这里插入图片描述

TCP连接管理(重点)

​ 假设运行在一台主机A的进程想与运行在另一台的主机B的进程建立连接,A的应用进程首先通知A的TCP,想与B的某个进程建立连接。A的TCP会以下方式建立一条TCP连接。

  • 第一步:A的TCP首先向B的TCP发送一个特殊的TCP报文段。该报文段不含有数据,首部的标志位SYN置为1,A会选择一个起始序列,放置到序号字段中。该报文段被封装在一个IP数据报中,发送给B,进入SYN_SENT状态

  • 第二步:当包含TCP SYN的报文段的IP数据到达了B,B会从数据报中提取出TCP SYN的报文段,并向A的TCP发送允许连接的报文,此时,会收到SYN泛洪攻击(防范措施:使用SYN cookies)。允许连接的报文的首部包含了SYN=1,确认号字段为A的序号+1,ACK=1,序号为B生成的序号,进入SYN_RCVD状态

    • SYN cookies:发起一个 TCP 连接时,客户端将一个 TCP SYN 包发送给服务器。作为响应,服务器将 TCP SYN + ACK 包返回给客户端。此数据包中有一个序号(sequence number,TCP头中的第二个32 bit),它被 TCP 用来重新组装数据流。
    • 根据 TCP 规范,当客户端发回 TCP ACK 包给服务器以响应服务器的 SYN + ACK 包时,客户端必须使用由服务器发送的初始序号加1作为数据包中的确认号。服务器接着从确认号中减去 1 以便还原向客户端发送的原始 SYN Cookie。
  • 第三步:收到SYN ACK报文后,A为该连接分配缓存河边。A还会向服务器发送另外一个报文段,这个报文段对服务器的允许连接的报文段进行了确认(A将B的序号+1放入确认号中,ACK=1),因为建立起连接了,SYN被置为0了,这时候就可以发送数据了。

    不使用两次握手的原因:首先,可能会出现已失效的连接请求又送到了服务器,如果客户机发出的第一个连接请求报文段没有丢失,而是在网络滞留了,导致延迟到连接释放的某个时候才到达服务器,服务器接收到后,向客户端发出请求报文,如果是三次握手的话,在一定时间没有收到客户端响应报文,就知道不需要建立连接;如果是两次握手的话,服务端接收到数据的话就会直接建立连接,等待客户端发送请求,但是客户端没有请求,就会浪费资源。

    **可以四次握手:**传输效率会降低,第二次握手:Server只会发送ACK和确认号,而Server的SYN和初始序号在第三次握手发送,原来协议中的第三次握手变为第四次握手。

    当第三次握手中,客户端的ACK报文没有送到服务器时,对服务端会重新发送SYN+ACK报文(默认是五次),客户端收到后会重新发送ACK给服务器;对于客户端:两种情况,一是在服务端超时重发时, 客户端已经发送数据了,服务器接收到数据后会读取确认号,加入establish状态;另一种是服务端进入CLOSED转台,如果客户端发送数据时,服务器会以RST包应答。

    如果建立了连接,客户端出现了故障,怎么办:服务器每次收到一次客户端的请求会重新建立一个复位计时器,时间通常时设置为2小时,若两小时还没有收到客户端的数据,服务器就会发送一个探测报文端,以后每隔75秒钟发送一次。如果一连发送10个探测报文仍然没有反应,服务器就认为客户端出了故障,接着就关闭连接。TCP的心跳机制,客户端每隔一小段时间向服务器发送一个数据包说明自己仍然在线,使用心跳包的典型协议是IM。心跳包的发送通常有两种技术:应用层自己实现心跳包,服务器在一个事件中定时,向客户端发送一个短小的报文,然后启动一个低级别的线程不断检测客户端的回应,如果在一定时间没有收到回应,就认为掉线,同理客户端中在一定时间内没有收到服务器的心跳包,就认为不可用了;第二种是TCP的KeepAlive保活机制,服务端和客户端使用TCP/IP的内置KeepAlive功能实现心跳功能就简单得多,默认超时时间为2小时,默认是不开启KeepAlive的功能。

TCP断开连接(重点)

​ 四次握手,当A或B中的某个TCP连接想要断开连接时,都可以断开。假设B想要断开连接,步骤为

  • 第一次握手:B发送一个特殊的TCP报文段,首部的标志位FIN置为1,序号为seq,进入FIN_WAIT_1状态

  • 第二次握手:A收到FIN报文时,发送一个ACK=1,确认号为seq+1,随机产生一个自己的序号,发送给B,此时B没有要发送的数据,但是可以接收A发送的数据

  • 第三次握手:B将FIN置为1,发送一个序号给A,进入LAST_ACK状态

  • 第四次握手:A收到B的FIN报文后,进入TIME_WAIT状态,接着将ACK置为1,发送确认号为第三次握手发送的序号+1给B;B收到报文后,确认了确认号后,变为CLOSED状态,不再向A发送数据。A等待2*MSL时间后,也加入CLOSED状态。

    为什么不能把服务器发送的ACK和FIN合并起来,变成三次握手(CLOSE_WAIT的状态意义是什么):因为服务器收到客户端断开连接请求时,可能还有数据没有发送完,这时回复ACK,表示接收到了断开连接的请求,等到数据发完之后再发FIN,断开服务器到客户端的数据传送。

    CLOSE_WAIT表示被动关闭,TIME_WAIT表示主动关闭。

    如果第二次挥手时服务器的ACK没有送达客户端,客户端会继续发送FIN报文。

    **客户端TIME_WAIT状态的意义是什么?**第四次挥手时,客户端发送给服务器的ACK有可能丢失,TIME_WAIT就是用来重发可能丢失的ACK,如果服务端没有收到ACK,就会重发FIN,如果客户端子2*MSL的时间内收到了FIN,就会重新发送ACK再等待2MSL(表示最大存活时间),防止服务端没有收到ACK而不断重发FIN。

TCP如何实现流量控制

​ 使用滑动窗口·协议实现流量控制。为了防止发送方发送速率超快·,导致接收方缓存区不够导致溢出,接收方会维护一个接收窗口,接收窗口大小是根据自己的资源情况动态调整的,在返回ACK时将接收窗口的大小放在TCP报文中的窗口字段告诉发送方。发送窗口的大小不能超过接收窗口的大小,只有发送方发送并收到确认之后,才能将发送窗口右移。

什么是零窗口:如果接收方没有能力接收数据时,就会将接收窗口置为零,这时发送方必须停止发送数据,但是会启动一个持续计时器,到期后发送一个探测数据包,如果接收方能接收数据了,就在返回报文中更新窗口大小。

TCP拥塞控制

​ 发送方维护一个叫拥塞窗口(cwnd)的状态变量,拥塞窗口的大小取决于网络的拥塞情况,会动态变化。发送方让自己的发送窗口等于拥塞窗口,而且又要考虑接收方的接收窗口,所以发送窗口一般会小于拥塞窗口。

​ 慢开始算法的思路就是,一开始不大量发送数据,先探测网络的拥塞程度,就是由小到大逐渐增加拥塞窗口大小。

​ 拥塞控制主要由四个算法组成:慢开始,拥塞避免,快重传,快恢复。

  1. 慢开始:刚开始发送数据时,先把拥塞窗口设置为最大报文段MSS的数值,每收到一个新的确认报文后,就把拥塞窗口加一个MSS。如此每经过一个传输轮次,拥塞窗口的大小就会加倍。

  2. 拥塞避免:当拥塞窗口的大小达到慢开始门限(slow start threshold)时,开始执行拥塞避免算法,拥塞窗口大小不再指数增加,而是线性增加,即每经过一个传输轮次只增加1 MSS。

    • 无论在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现了拥塞情况,就会将拥塞窗口降低为慢开始门限设置为出现拥塞时的发送窗口的一半。然后把拥塞窗口重新设为1,执行慢开始算法。
  3. 快重传:要求接收方在收到一个失序报文段就立即发出重复确认(为了早点使发送方及早知道有报文没有到达)而不等到自己发送数据时顺便确认。快重传算法规定,发送方只要连续接收到三个重复确认就立即重传对方尚未接收到的报文段,不需等待超时计数器。

  4. 快恢复:当发送方连续接收到了三个重复确认时,就把慢门限减半,然后执行拥塞避免算法。为什么不执行慢开始算法了,因为如果网络拥塞时,就不会连续收到三个重复确认,所以可以认为网络是无拥塞的。

  5. 快重传:要求接收方在收到一个失序报文段就立即发出重复确认(为了早点使发送方及早知道有报文没有到达)而不等到自己发送数据时顺便确认。快重传算法规定,发送方只要连续接收到三个重复确认就立即重传对方尚未接收到的报文段,不需等待超时计数器。

  6. 快恢复:当发送方连续接收到了三个重复确认时,就把慢门限减半,然后执行拥塞避免算法。为什么不执行慢开始算法了,因为如果网络拥塞时,就不会连续收到三个重复确认,所以可以认为网络是无拥塞的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值