计算机网络第三章——传输层

传输层服务

提供逻辑通信,传输层运行在端系统

网络层主机之间逻辑通信
传输层进程之间逻辑通信 可靠,增强网络层服务

Internet传输层协议
TCP、UDP("尽力传递"IP的直接拓展):将两个端系统间IP的交付服务拓展为运行在端系统上两个进程之间的交付服务

多路复用和多路分解

在这里插入图片描述

  • 接收主机多路分解:运输层报文段中的数据交付到正确的套接字
  • 发送主机多路复用:在源主机从不同套接字中收集数据块,并为每个数据块封装上首部信息(这将在以后用于分解)从而生成报文段,然后将报文段传递到网络层

多路分解工作原理:主机用IP地址和端口号指明数据段属于哪个合适的套接字

无连接多路分解

  • 端口号创建套接字
  • 当主机收到UDP数据段:
    • 检查数据段中的目的端口号
    • 端口号指示UDP数据段属于哪个套接字
  • 具有不同的源IP地址且/或源端口号,但具有相同的目的IP地址目的端口号的IP数据报,指向同样的套接字
  • 请求报文段中提供返回地址(包括IP地址和端口号)

面向连接多路分解

大量数据成帧,查看帧头,解封装,返回IP Packet,然后再解封转,返回segment
源IP地址源端口号目的IP地址目的端口号定位合适的套接字

UDP

特点:

  • 不需要建立连接(没有握手)——减少延迟
  • 简单:在收发之间不需要连接状态
  • 很小的数据报头,首部只有8字节,每个字段2字节
  • 没有拥塞控制:UDP能尽可能快的速度传递
  • UDP面向报文
    • 添加首部后向下交付给IP层,去除首部交付上层的应用程序
    • UDP不会合并或拆分报文,一次就发送一个报文

UDP首部格式

长度:首部和数据的总长度
校验和:用于差错检测,计算时,会临时把伪首部和UDP用户数据报连接在一起
伪首部格式
其中第三个字段用于填充对其
第四个字段表示协议类型:TCP-6,ICMP-58,UDP-17,此处是UDP协议,所以是17

校验和算法

  1. 计算checksum的数据每16bit划分为一段,如果最后有单个字节的数据,补一字节的0组成两字节
  2. 每个段累加到32bit上(求和时产生的进位回卷加到末位)
  3. 32bit再划分为两个16bit累加求和
  4. 取反(之所以取反是为了方便检验时计算出来的checksum和传过来的checksum相加为全1,然后再取反为0)

差错检测不能完全保证正确性,总会有错误

可靠数据传输(必考)

RDT:reliable data transfer
UDT:unreliable data transfer
上层调用rdt_send()将数据传送到下一层,接收应用层发送过来的数据
应用层 传输层 网络层之间

有限状态机(FSM):来标识发送方和接收方
逐步开发发送方和接收方的可靠的数据传输协议(rdt), 仅考虑单项数据传输但控制信息将双向流动

  • unforced state:
  • forced state:不会停留

基本框架
在这里插入图片描述
红线以上是网络应用层;红线下是不可靠信道,抽象的概念,把下层整合

RDT1.0

假设在完全可靠的信道上: 没有bit错误,没有分组丢失
发送方,接收方分离的FSMs: 发送方发送数据到下层信道; 接收方从下层信道接收数据

RDT2.0 具有bit错误的信道

应对方法: 检验和将检测到bit错误
增加机制:

  • 差错检验
  • 接收方反馈:控制信息(ACK确认; NAK否认,需要重发) rcvr->sender

在这里插入图片描述
在接收端因为不需要等待且和现有的状态不同,都只是在等下层的调用,所以也不用增加别的状态

如果传送多个数据包时,是一次发送完后再进等待,还是发一个等待一个?
发一个等一次回复

缺点:ACK和NAK会受损(信道不可靠),出现多重包
解决方法:增加编号,丢掉重复编号的包

rdt2.1:处理损坏的ACK/NAKs

发送方
在这里插入图片描述

序号的作用

为什么要判断两遍,判断是否损坏和NAK 然后又判断是ACK 损坏?
在2.1改进了
损坏和NAK都要重发.
如果接收端正常接收, 但是发送方无法识别包,所以会重发包.
既没有损坏也不是NAK,就是ACK进入等待上层调用1

为什么用0,1就可以

接收方
在这里插入图片描述
接收端收到的包如果序号不一样,可以判断出是重发了

就算判断出是重发了还是会返回ACK,只要这个包是正常的,都是会发送出ACK,感觉没什么作用?

rdt2.2:不再使用NAK

给ACK带上序号,就不需要再使用NAK
在这里插入图片描述
收到ACK1的原因: 接收端在等待0的状态下收到序号1的包,则返回ACK1–>那就是发送端发送了pkt1–>
发送端在发送pkt0的时候发生错误,接收端接收到损坏的pkt,就返回了ACK1

左下方出现seq1: 接收端接收到pkt1–>发送端发送了pkt1–>本应该发送pkt0但是发送了pkt1说明发生了重传–>发送端处于等待ACK0

rdt3.0 :出错且会丢包

方法:发送方等待一段时间

在这里插入图片描述
timer: 对方没有收到包; 网络延迟大;回复的报文丢失

为什么不在等待ACK0收到ACK1的时候做操作?
因为要将time清零,会增加复杂度.可以,但是不好. 在premature timeout避免无限重传

常见情况对应的收发端操作
在这里插入图片描述
在这里插入图片描述

性能分析

停等操作
传输时延:t=L/R
传播时延:RTT(一组传播时延、排队时延等)
T t r a n s m i t = L / R = 8 m s U s e n d e r = L / R R T T + L / R = 0.00027 T_{transmit}=L/R=8ms U_{sender}=\frac{L/R}{RTT+L/R}=0.00027 Ttransmit=L/R=8msUsender=RTT+L/RL/R=0.00027

改进

流水线技术:发送方允许发送多个“在路上的”还没确认的报文,

  • 序号的数目范围必须增加
  • 在发送方/接收方必须有缓冲区
Go-Back-N

GBN模型
发送方:在分组头中规定一个k位的序号 ; "窗口"允许的未确认的报文
接收到一个ACK后窗口向后滑动
ACK(n):确认所有的报文直到(包含)序号n - “累积ACK”对第一个发送未被确认的报文定时
超时(n):重发窗口中的报文n及以上更高序号的报文(只有一个定时器记录最早的未被确认报文的发送时间)
sand_base:窗口中已经发送的具有最小序号的报文
nextseqnum:可发送还未发送的报文

FSM
在这里插入图片描述
之所以只是用一个状态,最关键原因:因为有太多序号
接收方:总是位正确接收的最高序号的分组发送ACK

  • 可能生成重复的ACKs
  • 只记住被期待接收的序号
    接收到失序分组:丢弃(不缓冲),没有接收缓冲区,重发最高序号分组的ACK
    FSM
    在这里插入图片描述

GBN实例

wait的原因: 将窗口大小设为了4
第一次rcv pkt3返回ACK1:
因为pkt2丢失,导致接收到的分组时序,pkt1之前是正确的,所以2出问题,2之后的重发

选择性重传(Selective Repeat,SR)

基本思想

  • 接收方分别确认已经收到的分组(缓冲)
  • 发送者只重发没有收到确认的报文
  • 发送窗口:连续n个序号; 限制被发送的未确认的分组数量

模型
SR模型

分析上图的对应关系产生情况
rcv_base前四个已经正常接收到pkt了,并且返回了ACK,但是send_base后两个是没有接收到ACK

发送端

  • 从上层接收数据
  • 超时(n):重发分组n,并重启计时器
  • 收到ACK(n):标记分组n被接收; 如果n是最小的未确认分组,则窗口后移一格(窗口第一位为n,接收到ACKn,后移一位)

接收端(为什么又两个范围?)

  • 分组n的序号在[rcvbase, rcvbase+N-1]内
    • 发送ACK(n)
    • 失序分组: 缓冲
    • 有序分组: 交付上层 (包括已经缓冲的有序分组), 提高窗口到下一个没有接收的分组
  • 分组n在[rcvbase-N,rcvbase-1]内
    • 发送ACK(n)

例子
在这里插入图片描述
存在两难困境
在这里插入图片描述

窗口需小于或等于序号空间大小的一般

TCP

特点:

  • 点到点
  • 可靠按序的字节流
  • 流水线
  • 收发缓冲区
  • 全双工1数据:
  • 面向连接
  • 流量控制

报文段的首部格式

在这里插入图片描述
序号:数据段中第一个字节在数据流中的位置编号
确认号:期望从另外一边收到的下一个字节的序号
SYN:用于三次握手
ACK:累计ACK
窗口:window size 用于流控
校验和:要加上伪首部
在这里插入图片描述

TCP超时

要设置TCP的超时,必须要大于RTT,但是RTT变化
太短:不必要的重传
太长:对数据段丢失相应慢

估计RTT

样本RTT:测量从报文发送到接收到确认的时间——忽略重传
RTT均值(Estimated RTT) → \rightarrow
E s t i m a t e d R T T = ( 1 − α ) ∗ E s t i m a t e d R T T + α ∗ S a m p l e R T T Estimated RTT =(1- α)*Estimated RTT + α*Sample RTT EstimatedRTT=(1α)EstimatedRTT+αSampleRTT
典型的α=0.125
最开始会发送一个测试包,获得样本RTT
虽然可用,但是大部分还是难以覆盖

需要增加一个"安全余量"
D e v R T T = ( 1 − b ) × D e v R T T + b × ∣ S a m p l e R T T − E s t i m a t e d R T T ∣ T i m e o u t I n t e r v a l = E s t i m a t e d R T T + 4 ∗ D e v R T T DevRTT = (1-b) \times DevRTT +b \times |SampleRTT-EstimatedRTT|\\TimeoutInterval = EstimatedRTT + 4*DevRTT DevRTT=(1b)×DevRTT+b×SampleRTTEstimatedRTTTimeoutInterval=EstimatedRTT+4DevRTT

可靠数据传输

特点:

  • TCP在IP不可靠服务之上创建rdt服务
  • 流水线技术处理报文段
  • 累积确认
  • TCP 使用单个重发定时器
  • 触发重发:
    • 超时事件
    • 重复确认

发送方事件

  • 从应用程序接收数据
    • 用序号创造一个数据段
    • 序号是数据段中第一个数据字节在字节流中的位置编号
    • 如果没有启动定时器,则启动定时器
      • 定时器是最早没有被确认的数据段发送时启动的
      • 设置超时间隔: TimeOutInterval
  • 超时
    • 重发导致超时的数据段
    • 重新开始定时器
  • 收到确认
    • 如果确认了还没有确认的数据段
    • 更新还没有确认的状态
    • 还有未完成的数据段,重新开始定时器

序号逻辑

sendbase -1 =上一次ack的ack的字节
TCP会缓存乱序的报文

重传的场景

在这里插入图片描述

快速重传(在累积ACK上优化)

在timeout之前,当发现有重复(一般是3个)的ACK收到时
在这里插入图片描述

流量控制

速度匹配服务:发送速率和接收应用程序的提取速率减半
流量控制:发送方不能发送的太多太快,让接收缓冲区溢出
TCP连接的接收方有一个接收缓冲区,应用程序可能从缓冲区读出数据很慢

  • 实现方法
    • 滑动窗口协议(连续ARQ协议):接收方返回的ACK中回包含自己的接收窗口的大小

数据写入顺序:从低位地址开始写

连接管理

建立连接两次握手不行吗?
在这里插入图片描述
建立连接的三次握手
建立连接三次握手
关闭连接的四次握手
在这里插入图片描述

为什么建立连接是三次握手,断开连接是四次握手
建立连接本质上也是四次握手,接收双方要相互确认连接是否建立成功,但是中间两次可以合并成一次,即确认和请求同一次传输
因为连接时,调用socket的connect函数发送SYN包,而服务器端只是accept一下,就一次发送了SYN和ACK标志位,而到了断开连接时大家都要调用各自的close函数结束这段socket,所以两次close分别触发了两次FIN包,导致没有和ACK合并为一个包,所以握手3次,分手要4次。
因为发送方发送完数据包后,需要等待接收端处理完数据、发送完数据,即接收端也没有数据需要发送的时候

TCP FSM

在这里插入图片描述

拥塞控制

拥塞产生原因

  • 太多源主机发送太多数据,速度太快,以至于网络来不及处理
  • 表现
    • 丢失分组(路由器的缓冲区溢出)
    • 长延迟(在路由器的缓冲区排队)
场景
  • 单个路由器,缓冲区无限
  • 单个路由器,缓冲区有限
    • 时延过长,导致终端重发,使拥塞更加严重
  • 多个路由器
    • 当分组丢失后,任何上游路由器的发送能力都浪费了

拥塞控制方法

  • 端到端拥塞控制(TCP采用的方法)
    • 没有从网络中得到明确的反馈
    • 从端系统观察到的丢失和延迟推断出拥塞
  • 网络辅助的拥塞控制
    • 路由器给端系统提供反馈
    • 指明发送者应该发送的速率
    • 单bit指示拥塞(SNA, DECbit,TCP/IP ECN, ATM)

具体方法

L a s t B y t e S e n t − L a s t B y t e A C K e d < m i n ( C o n g W i n , R c v W i n ) 大 体 上 : r a t e = C o n g W i n R T T B y t e s / s e c LastByteSent -LastByteACKed < min(CongWin, RcvWin)\\ 大体上:rate = \frac{CongWin}{RTT} Bytes/sec LastByteSentLastByteACKed<min(CongWin,RcvWin):rate=RTTCongWinBytes/sec
CongWin(拥塞窗口,congestion window) : 最大可连续发送的数量(发送窗口大小)
通过丢包来感知拥塞:TCP发送方在丢失事件发生后降低发送速率

机制
  • 慢启动(slow start)
    • 开始连接时 CongWin = 1 MSS
    • 有效带宽将 >> MSS/RTT : 以2的指数方式增加速率知道产生丢失事件或达到阈值
  • 对拥塞事件作出反应
    • 超时事件发生时
      • CongWin立即设置为1个MSS
      • 窗口开始指数增长(进入慢启动),达到阈值(阈值也会下降)后再线性增长
    • 连续收到三个重复确认
      • CongWin 减半+3 (Reno版) ,然后开始线性增长
  • AIMD(Additive Increase Multiplicative Decrease)
    • 乘性递减:发生丢包事件后将拥塞窗口减半
    • 加性递增:每个RTT内如果没有丢失事件发生,拥塞窗口增加一个MSS
      慢开始和拥塞避免算法的实现举例(超时)
      新ssthresh值:24/2=12
      连续收到三个重复确认
      重视FSM的绘制
TCP拥塞控制的FSM图

在这里插入图片描述
TCP平均吞吐量
忽略慢启动,假设丢失发生时窗口大小为 W W W,则吞吐量为 W R T T \frac{W}{RTT} RTTW,丢失发生后,窗口下降为 W / 2 W/2 W/2,吞吐量为 W 2 R T T \frac{W}{2RTT} 2RTTW,则平均吞吐量为 0.75 W / R T T 0.75W/RTT 0.75W/RTT

TCP公平

  • 目标:K个TCP共享R宽带,每个应有R/K的平均速率
  • 丢失:减小窗口 ; 拥塞避免:增加窗口

  1. 同一时间点能收也能发;对讲机是半双工,同一时间一个机子只能接收或发送 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值