《计算机网络自顶向下方法》之传输层总结

导读

传输层基本理论和机制

  • 多路复用/分用
  • 可靠数据传输机制
  • 流量控制机制
  • 拥塞控制机制

传输层协议

  • UDP:无连接传输服务
  • TCP:面向连接的传输服务
  • TCP拥塞控制机制

    传输层概述

    传输层协议为不同主机上运行的进程提供逻辑通信机制(端到端的)

    网络层和传输层区别和联系:

    网络层是在主机之间提供逻辑通信机制

    传输层位于网络层之上,依赖网络层服务,对网络层服务进行(可能的)增强

发送方将消息分成一或多个报文段向下传给网络层,接收方将接收到的报文段组装成消息向上交付给应用层

  • TCP:可靠按序的交付服务
    • 拥塞控制
    • 流量控制
    • 连接建立
  • UDP:不可靠,基于“尽力而为”的网络层协议IP,没有做可靠性方面的扩展
  • 二者都不保证延迟、带宽

多路复用、分用

参考书上的收寄信件的案例,接收端多路分用(将数据报组合成信息),发送端多路复用(将信息拆分成多个数据报)

分用工作原理:

  • 主机接收到的IP数据报都携带源/目的IP地址,每个数据报都携带一个传输层的报文段(Segment),而报文段中携带源/目的端口号
  • 主机接收报文段后,传输层协议提取IP地址和端口号信息,报报文段导入正确的Socket中。(TCP有更多的处理过程)

分用对于UDP、TCP的区别:

  • UDP只依赖(二元组)源/目的端口号区别
  • TCP依赖 (四元组) 源/目的IP,源/目的端口号来区别

服务器可同时支持多个TCP Socket,服务器一个进程可以创建多个线程和不同TCP链接相连接,Web服务器为每个客户端都开不同的Socket

UDP协议(用户数据报协议)

基于IP协议实现了复用/分用,以及简单的错误检验(校验和)

因为IP是“尽力而为”的,所以UDP段可能丢失、可能不按序到达

每个UDP段的处理独立于其它段

UDP协议虽然是不可靠的,但依然可以在UDP上实现可靠数据传输。只要在应用层上增加可靠性机制、错误恢复机制

UDP协议的优势:

  • 无需建立连接(减少延迟)
  • 实现简单,不需要维护连接的状态
  • 头部开销小(8字节,TCP20字节)
  • 无拥塞控制,上层应用可更好地控制发送时间和速率

应用:常用于流媒体应用(容忍丢失,速率敏感),DNS,SNMP

UDP校验和使用,计算

  • 计算校验和

如果最高位有进位,要重新加在末尾(末尾再加1)

可靠数据传输(rdt)原理

可靠:不错、不丢、不乱

可靠数据传输对于应用层、传输层、链路层都很重要,它是计网中Top-10的问题。信道的不可靠特性决定了可靠数据传输协议的复杂性

Rdt协议基本结构图


注意我箭头所指出的,
数据传输单向,控制信息流动双向

Rdt 1.0:可靠信道上可靠数据传输协议(假设,现实不存在)

它认为底层信道完全可靠(不发生错误,不丢分组)

状态机(FSM),书上用来刻画传输协议的模型,去翻

Rdt 2.0:底层信道会产生位错误(bit翻转)

  • 错误如何检测?接收方利用校验和检测位错误 【检测机制】
  • 错误如何恢复?
    • 接收方向发送方反馈控制信息 【确认机制】
    • 确认机制(ACK),显式地告诉发送方分组已正确接收
    • NAK,告诉发送方分组有错误
    • 发送方接受NAK,重传分组 【重传机制】

基于这种重传机制的rdt称为ARQ(Automatic Repeat ReQuest)协议

停等协议,发送方有两种状态(等待接受上层应用数据【状态1】,等待反馈信息的接收【状态2】)

发送方在发送数据后,等待接收反馈信息,如果接收到ACK跳转到状态1等待上层调用;如果接收到NAK再次发送该分组(表明发送方有缓存机制),继续等待,直到接收到ACK

Rdt 2.1和2.2:解决2.0的缺陷

Rdt2.0协议的缺陷:反馈信息ACK/NAK有可能错误

Rdt2.1:

如何解决?

  1. 为ACK/NAK加上校验和,检错并纠错(难度大)
  2. 为ACK/NAK添加额外的控制信息(控制信息还可能错误)
  3. 如果ACK/NAK错误了,发送方就重传(但不能简单重传,会产生重复分组)【采用】

如何解决重复分组?

  • 发送方为每个分组增加序列号(Sequence number)0和1
  • 接收方丢弃重复分组

发送方、接收方使用停等协议,所以序列号只使用0和1就够用了

Rdt2.2:无NAK消息协议
功能同2.1,但是用ACK+序列号替代NAK(ACK消息中加入被确认分组的序列号)。比如说发送方等待序列号为0的分组ACK,但是接收到了序列号信息为1的ACK,表明有错误发生,重传该分组

Rdt 3.0:底层信道可能错误可能丢失分组

因为可能丢失分组,所以无论是发送方发送的分组丢失,还是接收方反馈的ACK/NAK丢失,都会造成双方无限等待的情况

如何解决?
设置定时器,发送方等待合理时间,如果超时还未接收到确认信息就重传。

合理时间要设置恰当,因为ACK反馈可能没丢,只是延迟了,但超时时间设置过小,你给他重传了

在2.2基础上改动,无NAK信息

发送方发送数据并启动定时器,若超时时间内收到了正确ACK信息跳转状态;若接收到错误ACK重传,定时器重启;若分组丢失,或者ACK丢失导致超时,发送方重传该分组并重启定时器;若ACK只是延迟,一样超时重传重启定时器

Rdt 3.0性能很低


解决效率低下问题————打破停等协议

  • 流水线机制
  • 滑动窗口协议(Sliding-window protocol):GBN、SR协议

序列号扩大,仅仅0和1不够用

流水线机制

允许发送方在接受到ACK回馈前可连续发送多个分组,要求扩大序列号范围,发送方接收方都要有缓存机制以缓存分组

理论上一次性发送分组越多效率越高

滑动窗口协议

如图,窗口大小为 N,绿色的是已确认分组,黄色是已发送等待确认分组数,蓝色是还可以发送分组数

  • 最多有N个等待确认分组
  • 随着协议运行,窗口在序列号空间内向前滑动
  • 如果此时发送方确认了最左端的一个黄色分组,窗口右滑一格

GBN回退N步协议

分组头部包含K位(K-bit)分组序号字段,序列号范围2^k

发送方

  • 窗口未满时可接受上层应用调用发送分组,如果已满,发送方将数据返回上层,隐示通知窗口已满
  • 累积确认机制:接收到ACK(n),表明到序列号n(含n)之前的分组均被正确接受
  • 分组的发送需要设置计时器一个计时器)
  • 如果发生序列号为n的分组超时旳事件,重传序列号大于等于n的所有还未接收到ACK确认的分组
  • 当接收到ACK(n)且n前面的所有分组都已确认,窗口滑动,base_sequence滑至尚未确认的分组处

重传存在资源浪费

接收方

  • 接收方按序交付数据给上层调用
  • 对于失序分组,接收方直接丢弃处理(因此不需要缓存机制)。因为序列号n+1的分组到达,但序列号n的分组丢失,发送方会把依重传机制把它们都重新发送即可
  • 接收方唯一需要维护的是下一个按序接收的分组序号
    • 接收方返回的反馈信息是 ACK(下一个要按序接收的分组序号-1) 【拥有最高序列号、已被正确接受的分组的ACK】

接收方无缓存机制,发送方有

例题:数据链路层依据GBN协议,发送方发送标号0~7的帧,计时器超时后,发送方只收到了0,2,3号帧的确认,需要重传哪几个帧?

不要想着1号帧,因为依据GBN原理,收到ACK(n)表明包含n在内的之前所有帧都已接收到了。所有是4,5,6,7

SR 选择重传协议 (Selective Repeat, SR)

解决GBN的不必要重传缺陷,不采用累积确认机制

接收方

  • 对每个分组单独确认,设置缓存机制(缓存乱序到达的分组)
  • 接收方也设置窗口
  • 失序分组被缓存,直到所有丢失分组(序列号更小)都被收到,才一次性交付给上层,接收窗口滑动交付分组数量长度
  • 接收到已确认的分组,任然要发送对应ACK

发送方

  • 每个分组设置单独的定时器,只重传没接收到ACK的分组

图解
图解

接收方窗口大小 + 发送方窗口大小 <= 序列号空间大小

发送方,接收方对于哪些分组正确接收,哪些没有并不总是能看到相同结果

TCP

全双工(full-duplex)服务,面向连接,点对点,同时发送接收

累积确认,双方都有缓存机制,使用超时/重传机制处理报文段丢失问题

三次握手 四次挥手

TCP报文段结构

TCP报文首部最小20B,最大60B(首部长度字段4bit,但是单位是B,4B*15=60B)

四元祖:

  • 源端口号:16bit
  • 目的端口号:16bit
  • 序列号Seq:32bit
  • 确认号Ack:32bit
  • Seq、Ack最重要

  • 接收窗口:用于流量控制,表示接收方愿接收的字节数

  • 6bit标志字段

超市间隔设置

  • 样本RTT(SampleRTT)
  • 样本RTT均值(EstimatedRTT)
  • RTT偏差(DevRTT):Samplertt和EstimatedRTT差值

样本RTT波动小,DevRTT值就小

TCP实现的服务

可靠数据传输

加倍超时间隔

拥塞时持续重传反而会加重拥塞,所以每次TCP重传都会将下一次超时间隔设置为先前值的两倍(这是一种有限形式的拥塞控制)

快速重传

因为加倍超时间隔有可能使得发送方等待很长时间才重传分组,增加了端到端的时延

快速重传讲究,未超时前提下,接收冗杂Ack(3次),快速重传该分组

冗杂Ack是什么?怎么产生?见课本P165

TCP是GBN还是SR协议

混合体,见书本p165

流量控制(流控制 flow-control)

速度匹配服务,发送方发送速率和接收方应用程序读速率相匹配,解决发送方使接收方缓存溢出的可能

流控制和拥塞控制都是对发送方的遏制

链接两端都维护一个接收窗口(receive window ,上文提过的首部字段),用来表明接收方当下还能接收的字节数

TCP概述

  • 点对点,端到端
  • 可靠按序的字节流,全双工的
  • 双方都有缓存机制
  • 流水线机制
    • 拥塞控制、流量控制机制
  • 面向连接的
    • 数据传输前必须建立连接
    • 连接状态只在两端维护,不涉及沿途节点
    • TCP连接包括:两台主机上的缓存、连接状态变量、socket等

TCP报文段结构(20~60字节)

  • 源/目的端口号
  • Seq:序列号
  • Ack:应答号

Seq是双方建立连接时随机取的,他指的是segment中第一个字节的编号,而非segment报文的编号

Ack是期望接收到的下一个字节的序列号,累计确认(表明该序列号前所有字节都已正确接收)

  • U、A、P、R、S、F
    • U:URG
    • A:ACK是否有效,1就是ACK有效
    • P:PSH,立刻向上交付数据(不怎么用)
    • RST、SYN、FIN涉及连接建立拆除
  • Receive Window:可接受的字节数

可靠数据传输概述

  • 基于IP层的不可靠服务基础上实现可靠数据传输服务
  • 流水线机制(提供传输效率)
  • 累计确认
  • TCP使用单一重传定时器
  • 触发重传事件:超时;收到重复ACK
  1. 如何设置超时时间
    • 大于RTT
    • 过短会造成不必要重传
    • 过长对段丢失时间反应慢
  2. RTT如何估计?超时设置多大?
    • 测量从报文段发出到接收到对应ACK的时间(样本RTT,SampleRTT) 【不考虑重传的报文段】
    • 测量多个SampleRTT,求平均得到RTT估计值EstimatedRTT
    • 测量RTT的变化值DevRTT:SampleRTT与EstimatedRTT的差值
    • 定时器超时时间设置为:$ TimeoutInterval = EstimatedRTT + 4*DevRTT$
  3. 发送方事件
    • 从上层应用收到数据
      1. 创建Segment,指定序列号(Segment第一个字节的编号)
      2. 开启计时器,设置超时时间
    • 超时
      1. 重传引起超时的Segment
      2. 重启定时器
    • 收到ACK
      1. 如果是以前未确认的Segment的ACk会更新SendBase,若窗口中还有未被确认的分组,则重启定时器
  4. 接收方行为
    • 接收到期望的Segment会延迟ACk发送(500ms,避免刚发就有其他Segment到达)
    • 接收到重复Segment,立刻发送ACK
    • 接收乱序Segment,立刻发送重复ACK(期望接收的字节序列号)
    • 至于乱序到达的Segment如何处理,有程序员决定

快速重传机制

  1. 如果发生超时,发送方超时间隔将会倍增

    这会使得超时间隔很大,重传之前要等待很久

  2. 通过重复ACk检测分组的丢失
    • 某个分组丢失可能引起多个重复ACk
    • 如果发送方收到对同一数据的3个ACk,就假定该数据之后的段已经丢失
  3. 快速重传:在定时器超时前进行重传

TCP流量控制

速度匹配,利用头部的RcvWindow字段

接收方告诉发送方RcvWindow=0,发送方仍然会发送一个非常小的段,以便接收方处理交付完数据后告知发送方需要的数据

TCP连接管理

  • 建立连接,三次握手
    1. 客户端向服务器发送SYN报文段(不携带数据,syn置1,携带初始序列号)
    2. 服务器同意,则发送SYNACK报文段,同时建立缓存和初始序列号
    3. 客户端接受到SYNACK后会答复一个ACK报文段(同时可携带数据)
  • 关闭连接,四次挥手
    1. client向Server发送FIN控制报文段
    2. Server收到FIN,回复ACK,进入等待,关闭连接,发送FIN
    3. client收到FIN,回复ACK
    4. Server收到ACK,连接关闭

拥塞控制原理

网络十大问题之一,表现在分组丢失(路由器缓存溢出)、分组延迟过大(在路由器缓存中排队

  1. 拥塞的代价

    • 分组延迟加大
    • 分组重传造成资源的浪费,降低吞吐率
    • 涉及多跳传输时,某个路由器将分组丢弃会导致‘上游’(前面经过的路由)传输能力全部浪费掉
  2. 控制的思想:控制发送速率

  3. 拥塞控制的方法
    • 端到端的拥塞控制
      1. 网络层不提供显示支持
      2. 由端系统通过观察数据loss,发送延迟delay等行为来判断是否拥塞
      3. TCP采取该方法
    • 网络辅助的拥塞控制
      1. 路由器向发送方显式地反馈拥塞信息
      2. 依赖简单的拥塞指示:SNA,DECbit,TCP/IP ECN,ATM使用

        ATM的拥塞控制 ABR(available bit rate)

  • 弹性服务
  • 发送方路径上负载低的话,发送方就会使用可用带宽;拥塞的话,就会将速率降低到最低保障速率

具体一点,ATM在网路上传输的是一个叫cell的(同之前所说的报文段),包含data cells、RM cells。通过RM cells控制拥塞,它由发送方发送,接收方再返回发送方,RM cell中有NI位(rate速率不许增长)、CI位(显式拥塞指示),和ER字段(2bit,显式的速率)

NI、CI是接收方反馈的,ER是直接交换机反馈的
交换机拥塞时,就可以将ER置为更小,发送方接收到后就能获知路径所能支持最小速率

定性机制(NI/CI),定量机制(速率字段ER)

数据cell中也有EFCI位:如果拥塞,交换机就把他置为1,那么发送方再返回的RM cell中置CI位(表明拥塞)

TCP如何控制拥塞

基本思想也是控制发送速率,设置变量CongWin(拥塞窗口)>= 发送的最后有一个byte的序列号 - 发送确认的最后一个应答后,rate ≈ CongWin/RTT

所以可以动态调整CongWin改变发送速率

采取机制:

  • 慢启动:SS
  • 拥塞避免(加性增,乘性减):AIMD

    如何判断网络拥塞

    发生超时,或者收到3个重复ACK,就可以判断拥塞

AIMD

线性增加发送速率,直到遇到拥塞发生,然后以减半的方式把速率降下来

  • 加性增:每个RTT将CongWin增大一个MSS—->拥塞避免

  • 乘性减:发生拥塞将CongWin减半

SS

TCP初始建立连接时一般把CongWin设为1个MSS,初始速率非常低(远小于带宽),考虑速率呈指数性质增长(慢启动),每一个经过RTT把CongWin翻倍

指数增长和加性增(线性增长)的转换条件

当CongWin达到(前一次发生拥塞事件时CongWin的一半,称为Threshold)时,由指数转为线性

发生拥塞后发送速率怎么变

  • 如果发生timeout,Threshold = CongWin/2,然后CongWin会直接减为1个MSS,然后慢启动
  • 如果是接收到3次重复ACk,Threshold = CongWin/2,然后CongWin = CongWin/2,然后线性增

timeout表明拥塞严重,而重复ACk表示还能发送一些数据

作业

  • 假设主机A向主机B发送5个连续的报文段,主机B对每个报文段进行确认,其中第二个报文段丢失,其余报文段以及重传的第二个报文段均被主机B正确接收,主机A正确接收所有ACK报文段;报文段从1开始依次连续编号(即1、2、3……),主机A的超时时间足够长。请回答下列问题:

1).如果分别采用GBN、SR和TCP协议,则对应这三个协议,主机A分别总共发了多少个报文段?主机B分别总共发送了多少个ACK?它们的序号是什么?(针对3个协议分别给出解答)

2).如果对上述三个协议,超时时间比5RTT长得多,那么哪个协议将在最短的时间间隔内成功交付5个报文段?


  • 假设A、B两个端系统通过唯一的一条8Mbps链路连接(M=10^6),该链路的双向传播时延是150ms;A通过一个TCP连接向B发送一个大文件,B的接收缓存足够大,每个TCP段最大段长度(MSS)为1500字节,TCP采用Reno版本,且总是处于拥塞避免阶段(即忽略慢启动)。请回答下列问题:

1).该TCP连接能够获得的最大窗口尺寸(以TCP段数计)是多少?

2).该TCP连接的平均窗口尺寸(以TCP段数计)和平均吞吐量(以bps计)是多少?

3).该TCP连接的拥塞窗口从发生丢包到恢复到最大窗口尺寸要经历多长时间?

觉得有帮助的话,不妨加个鸡腿,O(∩_∩)O哈哈~