第三章 传输层
1、概述和传输层服务
1.1 第三章:传输层
目标:
- 理解传输层的工作原理
- 学习Internet的传输层协议
- UDP:无连接传输
- TCP:面向连接的可靠传输
- TCP的拥塞控制
1.2 第三章:提纲
-
概述和传输层服务 -
多路复用与解复用 -
无连接传输:UDP -
可靠数据传输的原理 -
面向连接的传输: TCP
-
拥塞控制原理 -
TCP拥塞控制
1.3 传输服务和协议
- 为运行在不同主机上的应用进程提供逻辑通信
- 传输协议运行在端系统
- 发送方:将应用层的报文分成报文段,然后传 递给网络层
- 接收方:将报文段重组成报文,然后传递给应 用层
- 有多个传输层协议可提供选择:
1.4 传输层 VS 网络层
-
网络层服务:主机之间的逻辑通信 -
传输层服务:进程间的逻辑通信
- 依赖于网络层的服务:延时、带宽
- 并对网络层的服务进行增强:数据丢失、顺序混乱、加密
- 有些服务是可以加强的:不可靠 -> 可靠;安全
- 但有些服务是不可以被加强的:带宽,延迟
-
类比:东西2个家庭的通信 Ann家的12个孩子给Bill家的12个小孩发信
- 主机 = 家
- 进程 = 小孩
- 应用层报文= 信封中的信件
- 传输协议= Ann 和 Bill
- 网络层协议 = 邮政服务
1.5 Internet传输层协议
- 可靠的、保序的传输:TCP
- 不可靠、不保序的传输:UDP
- 多路复用、解复用
- 没有为尽力而为的IP服务添加更多的其它额外服务
- 都不提供的服务:
2、多路复用与解复用
2.1 多路复用/解复用
2.2 多路解复用工作原理
UDP和TCP不同
- 解复用作用:TCP或者UDP实体采用哪些信息,将报文段的数据部分交给正确的socket,从而交给正确 的进程
- 主机收到IP数据报
- 每个数据报有源IP地址和目标地址
- 每个数据报承载一个传输层报文段
- 每个报文段有一个源端口号和目标端口号(特定应用有著名的端口号)
- 主机联合使用IP地址和端口号将报文段发送给合适的套接字
2.3 无连接(UDP)多路解复用
-
创建套接字: 服务器端: serverSocket和Sad指定的端口号捆绑 客户端:
没有Bind,ClientSocket和OS为之分配的某个端口号捆绑(客户端使用什么端口号无所谓,客户端主动找服务器)
-
在接收端,UDP套接字用二元组标示(目标IP地址、目标端口号) -
当主机收到UDP报文段:
- 检查报文段的目标端口号
- 用该端口号将报文段定位给套接字
-
如果两个不同源IP地址/源端口号的数据报,但是有相同的目标IP地址和端口号,则被定位到相同的套接字 -
无连接多路复用:例子
2.4 面向连接(TCP)的多路复用
-
TCP套接字:四元组本地标识:
-
==解复用:==接收主机用这四个值来将数据报定位到合适的套接字 -
服务器能够在一个TCP端口上同时支持多个TCP套接字:
- 每个套接字由其四元组标识(有不同的源IP和源PORT)
-
Web服务器对每个连接客户端有不同的套接字
-
面向连接的解复用:例子
3、无连接传输:UDP
3.1 UDP:User Datagram Protocol [RFC 768]
- “no frills,” “bare bone”Internet 传输协议
- “尽力而为”的服务,报文段可能:
- 无连接:
- UDP发送端和接收端之间没有握手
- 每个UDP报文段都被独立地处理
- UDP被用于:
- 流媒体(丢失不敏感,速率敏感、应用可控制 传输速率)
- DNS
- SNMP
- 在UDP上可行可靠传输:
3.2 UDP:用户数据报协议
为什么要有UDP?
- 不建立连接(会增加延时)
- 简单:在发送端和接收端没有连接状态
- 报文段的头部很小(开销小)
- 无拥塞控制和流量控制:UDP可以尽可能快的发送报文段
3.3 UDP校验和
- 目标:检测在被传输报文段中的差错(如比特反转)
- 发送方:
- 将报文段的内容视为16比特的整数
- 校验和:报文段的加法和(1的补运算)
- 发送方将校验和放在UDP的校验和字段
- 接收方:
- 计算接收到的报文段的校验和
- 检查计算出的校验和与校验 和字段的内容是否相等:
- 不相等––检测到差错
- 相等––没有检测到差错 ,但也许还是有差错:残存错误
3.4 Internet校验和的例子
-
注意:当数字相加时,在最高位的进位要回卷,再加到结果上
- 目标端:校验范围+校验和=1111111111111111 通过校验
- 注:求和时,必须将进位回卷到结果上
4、可靠数据传输的原理
4.1 可靠数据传输(rdt)
rdt的原理
-
rdt在应用层、传输层和数据链路层都很重要 -
是网络Top 10问题之一 -
-
信道的不可靠特点决定了可靠数据传输协议(rdt)的复杂性
可靠数据传输:问题描述 我们将:
- 渐增式地开发可靠数据传输协议( rdt )的发送方和接
收方 - 只考虑单向数据传输
- 双向的数据传输问题实际上是2个单向数据传输问题的综
合 - 使用有限状态机 (FSM) 来描述发送方和接收方
4.2 Rdt1.0:在可靠信道上的可靠数据传输
- 下层的信道是完全可靠的
- 发送方和接收方的FSM
- 发送方将数据发送到下层信道
- 接收方从下层信道接收数据
4.3 Rdt2.0:具有比特差错的信道
- 下层信道可能会出错:将分组中的比特翻转
- 问题:怎样从差错中恢复:
- 确认(ACK):接收方显式地告诉发送方分组已被正确接收
- 否定确认(NAK): 接收方显式地告诉发送方分组发生了差错
- rdt2.0中的新机制:采用差错控制编码进行差错检测
- 发送方差错控制编码、缓存
- 接收方使用编码检错
- 接收方的反馈:控制报文(ACK,NAK):接收方->发送方
- 发送方收到反馈相应的动作
- rdt2.0:FSM描述
- rdt2.0:没有差错时的操作
- rdt2.0:有差错时
4.4 rdt2.1
- rdt2.0的致命缺陷->rdt2.1
如果ACK/NAK出错?
- 发送方不知道接收方发生了什么事情!
- 发送方如何做?
- 重传?可能重复
- 不重传?可能死锁(或出错)
- 需要引入新的机制
- 序号
**处理重复:**
- 发送方在每个分组中加入序号
- 如果ACK/NAK出错,发送方重传当前分组
- 接收方丢弃(不发给上层)重复分组
停等协议 发送方发送一个分组,然后等待接收方的应答
- rdt2.1:发送方处理出错的ACK/NAK
- rdt2.1:接收方处理出错的ACK/NAK
- rdt2.1:讨论
发送方:
- 在分组中加入序列号
- 两个序列号(0,1)就足够了
- 必须检测ACK/NAK是否出错(需要EDC)
- 状态数变成了两倍
- 必须检测接收到的分组是否是重复的
- 注意:接收方并不知道发送方是否正确收到了其ACK/NAK
- rdt2.1的运行
接收方不知道它最后发送的ACK/NAK是否被正确地收到
- 发送方不对收到的ack/nak给确认,没有所谓的确认的确认
- 接收方发送ack,如果后面接收方收到的是:
- 老分组p0?则ack 错误
- 下一个分组?P1,ack正确
4.5 rdt2.2
-
rdt2.2:无NAK的协议
- 功能同rdt2.1,但只使用ACK(ack要编号)
- 接收方对最后正确接收的分组发ACK,以替代NAK
- 当收到重复的ACK(如:再次收到ack0)时,发送方与收到NAK采取相同的动作:重传当前分组
- 为后面的一次发送多个数据单位做一个准备
- 一次能够发送多个
- 每一个的应答都有:ACK,NACK;麻烦
- 使用对前一个数据单位的ACK,代替本数据单位的nak
- 确认信息减少一半,协议处理简单
-
NAK free
高情商:把当前分组的反向确认用前面一个分组的正向确认来代替,这样就不用NAK了
-
rdt2.2的运行 -
rdt2.2:发送方和接收方片段
4.5 rdt3.0:具有比特差错和分组丢失的信道
-
==新的假设:==下层信道可能会丢失分组(数据或ACK)
-
==方法:==发送方等待ACK一段合理的时间
链路层的timeout时间确定的
传输层timeout时间是适应式的
- 发送端超时重传:如果到时没有收到ACK->重传
- 问题:如果分组(或ACK)只是被延迟了:
- 重传将会导致数据重复,但利用序列号已经可以处理这个问题
- 接收方必须指明被正确接收的序列号
- 需要一个倒计数定时器
-
rdt3.0 发送方 -
rdt3.0的运行
- 过早超时(延迟的ACK)也能够正常工作;但是效率较低,一半的分组和确认是重复的;
- 设置一个合理的超时时间也是比较重要的;
-
rdt3.0的性能 -
rdt3.0: 停-等操作 -
流水线:提高链路利用率 -
流水线协议 流水线:允许发送方在未得到对方确认的情况下一次发送多个分组
- 必须增加序号的范围:用多个bit表示分组的序号
- 在发送方/接收方要有缓冲区
- 发送方缓冲:未得到确认,可能需要重传;
- 接收方缓存:上层用户取用数据的速率≠接收到的数据速率;接收到的数据可 能乱序,排序交付(可靠)
- 两种通用的流水线协议:回退N步(GBN)和选择重传(SR)
4.6 GBN和SR
通用:滑动窗口(slide window)协议基本知识
-
发送缓冲区
- 形式:内存中的一个区域,落入缓冲区的分组可以发送
- 功能:用于存放已发送,但是没有得到确认的分组
- 必要性:需要重发时可用
-
发送缓冲区的大小:一次最多可以发送多少个未经确认的分组
- 停止等待协议=1
- 流水线协议>1,合理的值,不能很大,链路利用率不能够超100%
-
发送缓冲区中的分组
- 未发送的:落入发送缓冲区的分组,可以连续发送出去
- 已经发送出去的、等待对方确认的分组:发送缓冲区的分组只有得到确认才能删除
-
发送窗口:发送缓冲区内容的一个范围
-
发送窗口的最大值<=发送缓冲区的值 -
一开始:没有发送任何一个分组
-
每发送一个分组,前沿前移一个单位
发送窗口滑动过程-相对表示方法
- 采用相对移动方式表示,分组不动
- 可缓冲范围移动,代表一段可以发送的权力
发送窗口的移动->前沿移动
-
发送窗口前沿移动的极限:不能够超过发送缓冲区
发送窗口的移动->后沿移动
- 发送窗口后沿移动
- 条件:收到老分组的确认
- 结果:发送缓冲区罩住新的分组,来了分组可以发送
- 移动的极限:不能够超过前沿
滑动窗口技术
滑动窗口协议-接收窗口
-
接收窗口 (receiving window)=接收缓冲区
-
接收窗口的滑动和发送确认
- 滑动:
- 低序号的分组到来,接收窗口移动
- 高序号分组乱序到,缓存但不交付(因为要实现rdt,不允许失序),不滑动
- 发送确认:
- 接收窗口尺寸=1;发送连续收到的最大的分组确认(累计确认)
- 接收窗口尺寸>1;收到分组,发送那个分组的确认(非累计确认)
正常情况下的2个窗口互动
异常情况下GBN的2窗口互动
异常情况下SR的2窗口互动
GBN协议和SR协议的异同
- 相同之处
- 不同之处
- GBN :接收窗口尺寸=1
- 接收端:只能顺序接收
- 发送端:从表现来看,一旦一个 分组没有发成功,如:0,1,2,3,4; 假如1未成功,234都发送出去 了,要返回1再发送;GB1
- SR: 接收窗口尺寸>1
- 接收端:可以乱序接收
- 发送端:发送0,1,2,3,4,一旦1未成功,2,3,4,已发送,无需重发,选择性发送1
流水线协议:总结
- Go-back-N:
- 发送端最多在流水线中有N个未确认的分组
- 接收端只是发送累计型确认cumulative ack
- 发送端拥有对最老的未确认分组的定时器
- 只需设置一个定时器
- 当定时器到时时,重传所有未确认分组
- Selective Repeat:
- 发送端最多在流水线中有N个未确认的分组
- 接收方对每个到来的分组单独确认individual ack(非累计确认)
- 发送方为每个未确认的分组保持一个定时器
GBN:发送方扩展的FSM
GBN:接收方扩展的FSM
运行中的GBN
选择重传SR
- 接收方对每个正确接收的分组,分别发送ACKn(非累积确认)
- 发送方只对那些没有收到ACK的分组进行重 发-选择性重发
- 发送窗口的最大值(发送缓冲区)限制发送未确认分组的个数
选择重传
选择重传SR的运行
对比GBN和SR
- 适用范围:
- 出错率低:比较适合GBN,出错非常罕见,没有必要用复杂的SR,为罕见的事件做日常的准备和复杂处理
- 链路容量大(延迟大、带宽大):比较适合SR而不是GBN,一点出错代价太大
5、面向连接的传输:TCP
5.1 TCP概述
-
点对点
-
可靠的、按顺序的字节流:
-
管道化(流水线):
-
发送和接收缓存 -
全双工数据
-
面向连接:
- 在数据交换之前,通过握手(交换控制报文) 初始化发送方、接收方的状态变量
-
有流量控制:
5.2 TCP报文段
-
TCP报文段结构 -
TCP序号,确认号 序号:
确认号
-
TCP序号和确认号
5.3 TCP往返延时(RTT)和超时
-
Q:怎样设置TCP超时?
- 比RTT要长
- 太短:太早超时
- 太长:对报文段丢失 反应太慢,消极
-
Q:怎样估计RTT?
- SampleRTT:测量从报文段发出到收到确认的时间
- SampleRTT会变化,因此估计的RTT应该比较平滑
- 对几个最近的测量值求平均,而不是仅用当前的SampleRTT
-
-
5.4 可靠数据传输
-
TCP:可靠数据传输
- TCP在IP不可靠服务的基础上建立了rdt
- 管道化的报文段
- 累积确认(像GBN)
- 单个重传定时器(像GBN)
- 是否可以接受乱序的,没有规范
- 通过以下事件触发重传
- 首先考虑简化的TCP发送方:
-
TCP发送方(简化版) -
TCP发送方事件:
- 从应用层接收数据:
- 用nextseq创建报文段
- 序号nextseq为报文段首字节的字节流编号
- 如果还没有运行,启动定时器
- 定时器与最早未确认的报文段关联
- 过期间隔: TimeOutInterval
- 超时:
- 收到确认:
- 如果是对尚未确认的报文段确认
- 更新已被确认的报文序号
- 如果当前还有未被确认的报文段,重新启动定时器
-
TCP重传 -
产生TCP ACK的建议 -
快速重传
- 超时周期往往太长:
- 通过重复的ACK来检测报文段丢失
- 发送方通常连续发送大量报文段
- 如果报文段丢失,通常会引起多个重复的ACK
- 如果发送方收到同一数据 的3个冗余ACK,重传最小序号的段:
- 快速重传:在定时器过时之前重发报文段
- 它假设跟在被确认的数据后面的数据丢失了
- 第一个ACK是正常的;
- 收到第二个该段的ACK,表示接收方收到一个该段后的乱序段;收到第3,4个该段的ack,表示接收方收到该段之后的2个,3个乱序段,可能性非常大段丢失了
5.5 流量控制
- 接收方在其向发送方的TCP段头部的rwnd字段“通告”其空闲buffer大小
- RcvBuffer大小通过socket选项设置(典型默认大小为4096字节)
- 很多操作系统自动调整RcvBuffer
- 发送方限制未确认(“in-flight”)字节的个数≤接收方发送过来的rwnd值
- 保证接收方不会被淹没
5.6 连接管理
-
TCP连接管理 在正式交换数据之前,发送方和接收方握手建立通 信关系:
- 同意建立连接(每一方都知道对方愿意建立连接)
- 同意连接参数
-
同意建立连接 Q:在网络中,2次握手建立连接总是可行吗?
- 变化的延迟(连接请求的段没有丢,但可能超时)
- 由于丢失造成的重传 (e.g.req_conn(x))
- 报文乱序
- 相互看不到对方
-
2次握手的失败场景:
-
3次握手 -
3次握手解决:半连接和接收老数据问题 -
TCP:关闭连接
- 客户端,服务器分别关闭它自己这一侧的连接
- 一旦接收到FIN,用ACK回应
- 接到FIN段,ACK可以和它自己发出的FIN段一起发送
- 可以处理同时的FIN交换
-
TCP:关闭连接
6、拥塞控制原理
6.1 拥塞控制原理
- 拥塞:
- 非正式的定义: “太多的数据需要网络传输,超过了网络的处理能力”
- 与流量控制不同
- 拥塞的表现:
- 分组丢失 (路由器缓冲区溢出)
- 分组经历比较长的延迟(在路由器的队列中排队)
- 网络中前10位的问题!
6.2 拥塞的原因/代价:场景1
6.3 拥塞的原因/代价:场景2
-
理想化:发送端有完美的信息 -
理想化:掌握丢失信息 -
现实情况:重复 -
现实情况:重复
6.4 拥塞的原因/代价:场景3
6.5 拥塞控制方法
2种常用的拥塞控制方法:
- 端到端拥塞控制:
- 没有来自网络的显式反馈
- 端系统根据延迟和丢失事件推断是否有拥塞
- TCP采用的方法
- 网络辅助的拥塞控制:
- 路由器提供给端系统以反馈信息
- 单个bit置位,显示有拥塞 (SNA, DECbit, TCP/IP ECN, ATM)
- 显式提供发送端可以采用的速率
7、TCP拥塞控制
7.1 TCP拥塞控制:机制
端到端的拥塞控制机制:
- 路由器不向主机有关拥塞的反馈信息
- 路由器的负担较轻
- 符合网络核心简单的TCP/IP架构原则
- 端系统根据自身得到的信息,判断是否发生拥塞,从而采取动作
拥塞控制的几个问题:
- 如何检测拥塞
- 控制策略
- 在拥塞发生时如何动作,降低速率
- 在拥塞缓解时如何动作,增加速率
7.2 TCP拥塞控制:拥塞感知
发送端如何探测到拥塞?
-
某个段超时了(丢失事件):拥塞
- 超时时间到,某个段的确认没有来
- 原因1:网络拥塞(某个路由器缓冲区没空间了,被丢弃)概率大
- 原因2:出错被丢弃(各级错误,没有通过校验,被丢弃)概率小
- 一旦超时,就认为拥塞了,有一定误判,但是总体控制方向是对的
-
有关某个段的3次重复ACK:轻微拥塞
- 段的第1个ack,正常,确认绿段,期待红段
- 段的第2个重复ack,意味着红段的后一段收到了,蓝段乱序到达
- 段的第2、3、4个ack重复,意味着红段的后第2、3、4个段收到了 ,橙段乱序到达,同时红段丢失的可能性很大(后面3个段都到了, 红段都没到)
- 网络这时还能够进行一定程度的传输,拥塞但情况要比第一种好
7.3 TCP拥塞控制:速率控制方法
如何控制发送端发送的速率:
-
维持一个拥塞窗口的值:CongWin -
发送端限制已发送但是未确认的数据量(的上限):
LastByteSent-LastByteAcked ? CongWin
-
从而粗略地控制发送方的往网络中注入的速率
rate≈(CongWin/RTT)bytes/sec
-
CongWin是动态的,是感知到的网络拥塞程度的函数
- 超时或者3个重复ack,CongWin↓
- 超时时:CongWin降为1MSS,进入SS阶段然后再倍增到 CongWin/2(每个RTT),从而进入CA阶段
- 3个重复ack :CongWin降为CongWin/2,CA阶段
- 否则(正常收到Ack,没有发送以上情况):CongWin跃跃欲试↑
- SS阶段:加倍增加(每个RTT)
- CA阶段:线性增加(每个RTT)
TCP拥塞控制:策略概述
拥塞控制策略:
- 慢启动
- AIMD:线性增、乘性减少
- 超时事件后的保守策略
7.4 TCP慢启动
- 连接刚建立, CongWin = 1 MSS
- 如: MSS = 1460bytes & RTT = 200 msec
- 初始速率 = 58.4kbps
- 可用带宽可能>> MSS/RTT
- 当连接开始时,指数性增 加发送速率,直到发生丢 失的事件
- 当连接开始时,指数性增 加(每个RTT)发送速率 直到发生丢失事件
- 每一个RTT, CongWin加倍
- 每收到一个ACK时, CongWin加1(why)
- 慢启动阶段:只要不超时或 3个重复ack,一个RTT,CongWin加倍
- 总结: 初始速率很慢,但是 加速却是指数性的
7.5 TCP拥塞控制:AIMD
乘性减:
丢失事件后将CongWin降为1, 将CongWin/2作为阈值,进 入慢启动阶段(倍增直到 CongWin/2)
加性增:
当CongWin>阈值时,一个 RTT如没有发生丢失事件 ,将CongWin加1MSS: 探 测
-
当收到3个重复的ACKs:
- CongWin 减半
- 窗口(缓冲区大小)之后 线性增长
-
当超时事件发生时:
- CongWin被设置成 1 MSS,进入SS阶段
- 之后窗口指数增长
- 增长到一个阈值(上次发 生拥塞的窗口的一半)时 ,再线性增加
思路:
- 3个重复的ACK表示网络 还有一定的段传输能力
- 超时之前的3个重复的 ACK表示“警报”
-
改进 Q: 什么时候应该将 指数性增长变成 线性? A: 在超时之前,当 CongWin变成上次发生超时的窗口的一半 实现:
- 变量:Threshold
- 出现丢失,Threshold设置成 CongWin的1/2
7.6 总结:TCP拥塞控制
-
当CongWin<Threshold, 发送端处于慢启动阶段(slow-start), 窗口指数性增长. -
当CongWin〉Threshold, 发送端处于拥塞避免阶段(congestion-avoidance), 窗口线性增长 -
当收到三个重复的ACKs (triple duplicate ACK), Threshold设置成 CongWin/2, CongWin=Threshold+3 -
当超时事件发生时timeout, Threshold=CongWin/2 CongWin=1 MSS,进入SS阶段 TCP发送端拥塞控制
总结:TCP拥塞控制
TCP吞吐量
-
TCP的平均吞吐量是多少,使用窗口window尺寸W和RTT来 描述?
-
W:发生丢失事件时的窗口尺寸(单位:字节)
- 平均窗口尺寸(#in-flight字节):3/4W
- 平均吞吐量:RTT时间吞吐3/4W
7.7 TCP公平性
公平性目标: 如果 K个TCP会话分享一个链路带宽为R的瓶颈,每一个会话的有效带宽为 R/K
-
为什么TCP是公平的? 2个竞争的TCP会话:
- 加性增加,斜率为1, 吞吐量增加
- 乘性减,吞吐量比例减少
-
公平性和 UDP
- 多媒体应用通常不是用 TCP
- 使用UDP:
- 音视频应用泵出数据的速率是恒定的, 忽略数据的丢失
- 研究领域: TCP 友好性
-
公平性和并行TCP连接
- 2个主机间可以打开多个并行的TCP连接
- Web浏览器
- 例如: 带宽为R的链路支持了9个连接:
- 如果新的应用要求建1个TCP连接,获得带宽R/10
- 如果新的应用要求建11个TCP连接,获得带宽R/2
8、 总结
-
传输层提供的服务
- 应用进程间的逻辑通信
- 互联网上传输层协议:UDP TCP
-
多路复用和解复用
- 端口:传输层的SAP
- 无连接的多路复用和解复用
- 面向连接的多路复用和解复用
-
实例1:无连接传输层协议UDP
-
可靠数据传输原理
-
问题描述 -
停止等待协议:
- Rdt1.0
- rdt2.0
- rdt2.1
- rdt2.2
- Rdt3.0
-
流水线协议
是按照接收窗口来区分:
- GBN接收窗口等于1,只能按顺序接收,如果不是期待的分组则被丢弃
- SR接收窗口大于1,可以乱序接收,只需要重发没有接收到的分组即可
-
实例2:面向连接的传输层协议-TCP
- 概述:TCP特性
- 报文段格式
- TCP可靠传输机制
- 重传,快速重传
- 流量控制
- 连接管理
-
拥塞控制原理
-
TCP的拥塞控制
|