Computer_Network_TransLayer

Trans_Layer

传输层概述

传输层的功能

  • 为运行在不同主机上的应用进程提供逻辑通信
  • 传输协议运行在端系统
    • 发送方:将应用层的报文分成报文段,然后传递给网络层
    • 接收方:将报文段重组成报文,然后传递给应用层
  • 复用和分用(multiplexing / demultiplexing)
  • 传输协议
    • TCP/UDP
  • 传输层 VS. 网络层
    • 网络层服务:主机之间的逻辑通信
    • 传输层服务:进程间的逻辑通信

多路复用与解复用

多路复用与解复用的概念多路复用与解复用

  • 多路复用:在发送方主机多路复用,从多个套接字接收来自多个进程的报文,根据Socket对应的IP地址和端口号等信息对报文段用头部加以封装
  • 多路解复用:在接收方主机多路解复用,根据报文段的头部信息中的IP地址和port将接收到的报文段发给正确的Socket

多路解复用中UDP与TCP的区别

  • 多路解复用工作原理

    • UDP Socket编程(引)UDP_Socket

      • 无连接:指的是在客户端和服务器之间没有连接,没有握手
      • Socket是一个二元组,仅指定目标的IP和Port
      • 服务器必须从收到的分组中提取出发送端的IP和Port
    • TCP Socket编程TCP_Socket

      • 有连接
      • Socket是一个四元组源IP、Port,目标IP、Port
    • UDP(无连接)多路解复用

      • 解复用是由运输层到应用层的过程,将数据报解封装,定位到对应的Socket

      • 由于UDP Socket是一个二元组,那么对于目标IP和Port一致的数据报被定位到相同的Socket

    • TCP多路解复用

      • TCP是有连接的协议,所以根据四元组的信息定位Socket,只有四元组的信息完全一致,才定位到同一个Socket
  • 多路复用工作原理

    • 多路复用则是数据报由应用层封装到运输层的过程
    • UDP(无连接)多路复用:由于UDP的Socket是二元组,没有源IP和Port,所以在运输层中,运输层为数据报加上源端口号和目的端口号,网络层再为数据报封装上源IP和目的IP
    • TCP多路复用

无连接传输:UDP(User Datagram Protocol)

UDP传输的特点

  • 无连接,不可靠,协议数据单元为用户数据报可靠性差,但传输效率好,实时性好。适用于只对数据传输的实时性要求较高,但对传输质量要求低的场景,如在线语音、视频聊天等。
  • 在传送数据之前**不需要先建立连接。**发送完数据后,不需要接到对方的确认。
  • 虽然 UDP 不提供可靠交付,但在某些情况下 UDP 是一种最有效的工作方式(例如流式媒体运输,如视频电话等)
  • UDP 是面向报文的。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。UDP 一次交付一个完整的报文
  • UDP 没有拥塞控制,因此网络出现的拥塞不会使源主机的发送速率降低。这对某些实时应用是很重要的。很适合多媒体通信(如IP电话、视频会议)的要求。 (但是,如果多个源主机上的进程使用UDP同时向网络发送实时视频流时,可能导致拥塞)
  • 常用UDP的应用和应用层协议:DNS、TFTP、RIP、DHCP、SNMP、NFS、IGMP等

UDP报文格式以及UDP校验和

UDP报文格式

UDP报文组成:头部+数据

  • 其中头部只有4个字段源端口、目的端口、报文长度、校验和,共计8个字节
  • 这四部分均占16位,即2字节,共计8字节
  • UDP支持的最长报文长度:由于报文长度占16位,故理论上UDP报文可达 2^{16}​ 字节,也即65535字节,除去头部8字节,为65535-8字节;另一方面,UDP数据报还要加上IP包头部,其中IP包头部又占20字节,故最终其数据报最大可达:65535-8-20

UDP校验和

  • 发送方
    • 将报文段的ip为头部、UDP头部和数据部分拼成一个16位的二进制数
    • 校验和:报文段的加法和(1的补运算)
    • 将校验和放在UDP的校验和字段
  • 接收方
    • 计算接收到的报文段的校验和
    • 检查计算出的校验和与校验和字段的内容是否相等
    • 若相等:没有检测到差错,但也许还是有差错;若不相等:检查到差错

可靠数据传输的原理

可靠数据传输概述(Reliable Data Trans)

rdt框架

如图是可靠数据传输的框架,为上层实体提供的服务抽象是:数据可以通过一条可靠的信道进行传输,借助可靠信道传输数据比特不会受到损坏或丢失,而且所有数据都是按照发送顺序交付的

构建可靠数据传输协议

Rdt1.0:在可靠信道上的可靠数据传输

  • 下层的信道是完全可靠的:没有比特出错,没有分组丢失
  • 发送方和接收方的FSM(有限状态机)rdt1.0
    1. 如上图所示,rdt的发送端通过rdt_send(data)事件将来自上层的数据处理,并通过make_pkt进行分组,并将分组发送到信道中
    2. 如图b,rdt的接收端通过rdt_rcv(packet)将来自下层的分组接收,并通过动作extract将分组中取出数据data,然后将数据交给上层

Rdt2.0:具有比特差错的信道

  • 下层信道可能会出错:将分组中的比特翻转,继续假定所有发送的分组不会丢失,所有分组(虽然比特可能受损)将按其发送的顺序被接收。

  • 解决办法:通过校验和来检测比特差错

  • 怎么从差错中恢复?

    • (ACK):接收方显式地告诉发送方分组已被正确接收
    • (NAK):接收方显式地告诉发送方分组发生了差错,发送方受到NAK之后,进行分组重传
  • FSM描述

    rdt2.0

    1. 对于发送方,若收到NAK则需要分组重传;若收到ACK则不必重传
    2. 对于接收方,对接收的分组进行差错校验,若发生错误,向发送方发送NAK,反之发送ACK

Rdt2.1:2.0版本的修订版

  • rdt2.0有一个致命缺陷,即没有考虑ACK/NAK分组受损的情况以及纠正ACK/NCK分组中的差错,当ACK/NAK分组受损,发送方无法知道接收方是否正确接收了发送的数据,就无法进行下一步相应
  • 解决方案:引入了冗余分组,即发送方收到受损的ACK/NCK不知道接收方的意思时,只需要重传当前的分组即可,这种方法的问题:接收方不知道它上次发送的ACK/NAK是否被发送方正确地收到,因此它并不知道到达的分组是新的分组还是一次重传,解决这个办法的办法是:在数据分组中添加一个新字段,让发送方对其数据分组编号,即将发送数据的序号放在该字段,就知道是否是重传的分组
  • rdt2.1的实例运行rdt2.1

Rdt 2.2:无NAK的协议

  • 功能和rdt2.1几乎一致,但是接收方只是用ACK(ACK需要进行编号
  • 接收方对最后正确接收的分组发ACK,以代替NAK
  • 若发送方收到重复的NAK,则需要进行分组重传
  • rdt2.2的运行实例rdt2.2

Rdt 3.0:具有比特差错和分组丢失的信道

  • 假定下层信道除了比特受损,还会丢包但所有分组还是按照其发送的顺序接收

  • Rdt3.0在2.2的基础上解决丢包问题,因此引入了超时重传机制,为了实现这个机制,引入了一个倒计数定时器,当发送方每发送一个分组,便启动一个定时器,定时器中断,采取适当动作,终止定时器。

  • Rdt3.0的性能分析:如下图所示,每次收到ACK确认后发送方才发送下一个分组,效率极低Rdt3.0_停等

流水线可靠数据传输协议

  • 在Rdt3.0的基础上提高链路的利用率允许发送方在未得到对方确认的情况下发送多个分组
  • 必须增加序号的范围
  • 在发送方/接收方都要设置缓冲区:对于发送方缓冲区大小至少为已发送但没有确认分组的大小;对于接收方,缓冲区大小至少为接收成功的分组大小
  • 两种通用的流水线协议:GBN【回退N步】和SR【选择重传】

GBN协议(回退N步/滑动窗口协议)

  • GBN协议依赖于一个滑动窗口,要求未确认的分组数不能超过最大允许数N
  • 虚拟窗口的设置:Slide_Window
    • 基序号(base):最早未确认分组的序号
    • nextseqnum:下一个待发送分组的序号
    • 该窗口分为四段第一段为已发送已确认分组,第二段为已发送未确认分组,第三段为未发送待发送分组,第四段为未发送分组
  • GBN存在的问题:接收方为了防止分组乱序,丢弃大量分组浪费资源clip_image015
    • 如上图所示:窗口长度为4个分组的GBN协议的运行情况;
    • 发送方首先发送分组0~3,然后在继续发送之前,必须等待直到一个或多个分组被确认。
    • 当接收到每一个连续的ACK(如ACK 0、ACK 1),该窗口便向前滑动,发送方就可以发送新的分组(分组4和分组5)。
    • 在接收方,分组2丢失,因此在分组3到达时发现不是与1连续的分组,就丢弃分组3并发送ACK 1(分组1)。
    • 在发送方未超时重新发送分组2,并接收到分组2的反馈分组之前,为了保证到达的分组有序,其余到达接收方的分组都会被丢弃。

SR协议(选择重传)

  • 避免“GBN中单个分组出错或丢失就会引起大量的分组被重传”的问题,选择重传通过让发送方仅重传那些它怀疑在接收方出错的分组而避免不必要的重传。

  • SR的解决方案SR

    • 发送方的动作
      1. 从上层接收数据,当从上层接收到数据后,SR发送方检查下一个可用于该分组的序号。如果序号位于发送方的窗口内,则将数据打包并发送;否则就像在GBN中一样,要么将数据缓存,要么将其返回给上层以便以后传输。
      2. 超时。仍采用定时器防止丢失分组,但是与GBN不同的是,现在每个分组必须拥有自己的逻辑定时器,因为超时发生后只能发送该超时的分组。可以使用单个硬件定时器模拟多个逻辑定时器的操作。
      3. **收到ACK。**如果收到ACK,倘若该分组序号在窗口内,则SR发送方将那个确认的分组标记为已接收。如果该分组序号等于send_base(即窗口内第一个发送的分组被正确接收),则窗口基序号向前移动到具有最小序号的未被确认的分组处。如果窗口移动了并且有序号落在窗口内的未发送分组,则发送这些分组。
    • 接受方的动作(只考虑窗口内及窗口前面的分组)
      1. **序号在[rcv_base,rcv_base+N-1]内的分组被正确接收。**此情况下,收到的分组落在接收方的窗口内,一个选择ACK被反馈给发送方。如果该分组以前没有收到过,则缓存该分组。如果该分组的序号等于接收窗口的基序号,则该分组以及以前缓存的序号连续的分组交付给上层。然后,接收窗口按向前移动分组的编号并向上交付这些分组。
      2. **序号在[rcv_base-N,rcv_base-1]内的分组被正确接收到。**此情况下,必须产生一个ACK,即使该分组是接收方以前已确认过的分组。
      3. **其他情况。**忽略该分组。
  • SR实例SR-实例

面向连接的传输:

TCP概述(Trans Control Protocol)

  • 面向连接:TCP是一种面向连接的协议,在数据传输之前必须先建立连接,然后再进行数据传输,数据传输完成后,再释放连接。
  • 全双工:数据双向流动
  • 面向字节流:将数据视为连续的字节流进行传输,而不是将数据划分为消息或数据包,没有报文边界
  • 拥塞控制
  • 流量控制

TCP报文段结构

TCP报文段

TCP:提供可靠数据传输

  • TCP在IP不可靠的服务的基础上建立了Rdt(reliable data trans)
  • 通过以下事件触发重传
    • 超时
    • 重复的确认
  • 快速重传:通过重复的ACK来检测报文分组的丢失,若报文段丢失,通常会引起多个重复的ACK
    • 不必等到定时器过时
    • 当遇到冗余ACK,假设跟在当前ACK后面的数据报全部丢失,全部重传

TCP:流量控制

  • 流量控制:通过接收方,控制发送方的速率不要太快,既要让接收方来得及接收,也不要使网络发生拥塞。点对点,通过接收窗口实现流量控制
  • TCP 报文段实现流量控制TCP报文段
    • 字节流方式
    • 通过接收方的窗口大小控制接收方滑动窗口

TCP:连接管理

  • 三次握手——连接建立三次握手
    • 第一次握手:客户端向服务端发送一个 SYN =1(连接请求),并指明客户端的初始化序列号 ISN(x),即图中的 seq = x表示本报文段所发送的数据的第一个字节的序号。此时客户端处于 SYN_Send 状态:在发送连接请求后等待匹配的连接请求
    • 第二次握手:服务器收到客户端的 SYN 报文之后,会发送 SYN 报文作为应答(SYN = 1),并且指定自己的初始化序列号 ISN(y),即图中的 seq = y。同时会把客户端的 ISN + 1 作为确认号 ack 的值,表示已经收到了客户端发来的的 SYN 报文,希望收到的下一个数据的第一个字节的序号是 x + 1,此时服务器处于 SYN_REVD 的状态:在收到和发送一个连接请求后等待对连接请求的确认
    • **第三次握手:**客户端收到服务器端响应的 SYN 报文之后,会发送一个 ACK 报文,也是一样把服务器的 ISN + 1 作为 ack 的值,表示已经收到了服务端发来的的 SYN 报文,希望收到的下一个数据的第一个字节的序号是 y + 1,并指明此时客户端的序列号 seq = x + 1(初始为 seq = x,所以第二个报文段要 +1),此时客户端处于 Establised 状态。服务器收到 ACK 报文之后,也处于 Establised 状态,至此,双方建立起了 TCP 连接。
  • 四次挥手——连接关闭四次挥手
    • 为什么要进行四次挥手:由于TCP连接的半关闭特性两次挥手只能关闭单侧的连接,再来两次关闭另一侧
    • 第一次挥手:客户端发送一个 FIN 报文(请求连接终止:FIN = 1),报文中会指定一个序列号 seq = u。并停止再发送数据,主动关闭 TCP 连接。此时客户端处于 FIN_WAIT1 状态,等待服务端的确认。
    • 第二次挥手:服务端收到 FIN 之后,会发送 ACK 报文,且把客户端的序号值 +1 作为 ACK 报文的序列号值,表明已经收到客户端的报文了,此时服务端处于 CLOSE_WAIT 状态。此时的 TCP 处于半关闭状态,客户端到服务端的连接释放
    • 第三次挥手:如果服务端也想断开连接了(没有要向客户端发出的数据),和客户端的第一次挥手一样,发送 FIN 报文,且指定一个序列号。此时服务端处于 LAST_ACK 的状态,等待客户端的确认。
    • 第四次挥手:客户端收到 FIN 之后,一样发送一个 ACK 报文作为应答(ack = w+1),且把服务端的序列值 +1 作为自己 ACK 报文的序号值(seq=u+1),此时客户端处于 TIME_WAIT (时间等待)状态

拥塞控制原理

拥塞概述

  • 拥塞:网络中的数据超出了网络的处理能力

  • 拥塞的表现

    • 分组丢失(路由器缓冲区溢出)
    • 分组经历比较长的延迟(在路由器的队列中排大队)
  • 拥塞控制:防止过多的数据注入到网络中,使网络的路由器或链路不至于过载

  • 拥塞控制Vs.流量控制:

    • 流量控制往往指点对点通信量的控制,是个端到端的问题(接收端控制发送端)。流量控制所要做的就是抑制发送端发送数据的速率,以便使接收端来得及接收。
    • 拥塞控制是一个**全局性(整个网络)**的过程,涉及到所有的主机、所有的路由器,以及与降低网络传输性能有关的所有因素。
    • 二者的共同点就是:目的都是降低数据发送速率。都是基于窗口的,接收窗口rwnd和拥塞窗口cwnd
  • 如何判断发生了拥塞

    • 重传定时器超时
    • 收到冗余的ACK
  • 拥塞控制方法:

    TCP发送方维持一个拥塞窗口 CWND 拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量。所以,发送窗口大小不仅取决于接收方公告的接收窗口,还取决于网络的拥塞状况,所以真正的发送窗口值为:min(接收窗口,拥塞窗口)

TCP拥塞控制

TCP拥塞感知

  • 某个段超时:网络拥塞,对应控制方法的慢开始
  • 冗余ACK:网路轻微拥塞,对应控制方法的快开始

TCP拥塞控制方法

TCP发送方维持一个拥塞窗口 CWND 拥塞窗口的大小取决于网络的拥塞程度,并且动态地在变化。发送端利用拥塞窗口根据网络的拥塞情况调整发送的数据量。所以,发送窗口大小不仅取决于接收方公告的接收窗口,还取决于网络的拥塞状况,所以真正的发送窗口值为:min(接收窗口,拥塞窗口)

TCP拥塞控制算法

  • 慢开始由小到大逐渐增大拥塞窗口数值,每一个传输轮次对拥塞窗口进行加倍
    • 启动初值很低
    • 增速很快,指数级增速
  • 快恢复(AIMD算法):当发送端收到连续三个重复的确认时,由于发送方现在认为网络很可能没有发生拥塞,而是报文产生了丢失,问题没有那么严重。因此现在不执行慢开始算法
    • 发送方窗口数折半
    • 拥塞窗口缓慢的线性增大
  • 拥塞控制实例拥塞控制

参考文献:

可靠数据传输原理 - Aidan_Chen - 博客园 (cnblogs.com)

φ(゜▽゜*)♪咦,又好了! (gitee.io)

中科大郑烇、杨坚全套《计算机网络(自顶向下方法 第7版,James F.Kurose,Keith W.Ross)》课程_哔哩哔哩_bilibili

java - 💯 关于 TCP 三次握手和四次挥手,满分回答在此 - 个人文章 - SegmentFault 思否


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2542608082@qq.com