UDP和TCP的对比
UDP | TCP | |
支持连接吗 | 无连接 | 面向连接
|
支持单播多播广播吗 | 支持单播多播和广播 支持一对一,一对多,一对全 | 仅支持单播,也就是一对一的连接,因为是在一条可靠信道中进行交流 |
面向谁 | 面向应用报文,既不合并,也不拆分 | 面向字节流 |
连接可靠性 | 无连接不可靠的传输服务 监测到错误,仅丢弃 不使用流量控制和拥塞控制 | 面向连接的可靠服务 不会出现误码丢失乱序重复的传输差错 可靠传输,流量控制,拥塞控制 |
适用情况 | 适用于IP电话,视频会议等实时应用 | 要求可靠的传输应用,例如文件传输 |
首部 | ![]() | ![]() |
TCP的流量控制
一般来说,我们总是希望数据传输得更快一些。太快,接收方来不及接收,数据会丢失
流量控制,发送方的发送速率不要太快,要让接收方来得及接收
利用滑动窗口机制可以很方便地在TCP连接上实现对发送方的流量控制
通过发送窗口去控制流量控制
接收方根据自己的缓存情况,来控制发送方的发送数量
黄色部分为死锁
启动持续计时器来解决死锁的局面
零窗口探测报文也有持续计时器
TCP的拥塞控制
某段时间,若对网络中某一资源需求超过了该资源所提供的可用部分,网络性能就要变坏。
带宽、交换结点中的缓存和处理机等,都是网络资源。
若出现拥塞而不进行控制,则网络的吞吐量将随输入负荷的增大而下降
四种拥塞控制算法基本原理
- 慢开始指一开始 向网络注入的报文段少,并不是指cwnd增长速度慢
- 拥塞避免不是完全避免拥塞,而是在要塞阶段将拥塞窗口控制为线性规律增长,使网络不易拥塞
发送方维护一个叫做拥塞窗口cwnd状态变量,其值取决于网络拥塞程度,并动态变化
- cwnd的维护原则:只要网络没有拥塞,拥塞窗口就增大些;但只要拥塞,拥塞窗口就减少一些
- 判断拥塞依据:没按时收到确认报文(即发生超时重传)
发送方将拥塞窗口作为发送窗口swnd,即swnd = cwnd
维护一个慢开始门限ssthresh状态变量
- cwnd<ssthresh时,使用慢开始算法
- cwnd>ssthresh时,停止使用慢开始算法而改用拥塞避免算法
- cwnd=ssthresh时,既可用慢开始,也可以用拥塞避免算法
过程阐述
传输轮次:发送方发过报文段,接收方发回相应确认报文段
按照慢开始→拥塞避免→慢开始....的顺序进行拥塞控制
- 第一段进行慢开始,每个轮次数值都是指数增加的,直到到达ssthresh值
- 第二段是拥塞避免:拥塞窗口值每轮次线性+1,直到出现了某种错误,比如超时重传
- 第三段慢开始算法,发送方觉得网络可能出现了拥塞,进行以下工作
将ssthresh值更新为cwnd的一半
将cwnd值减为1,并且重新开始执行慢开始算法
过程总结如下
慢开始和拥塞算法是TCP拥塞控制算法
快重传算法
- 改进TCP性能,又增加了两个拥塞控制算法,
- 原因:有时,报文丢失,但是网络未拥塞,发送方会超时重传,误解网络拥塞, 发送方把拥塞窗口cwnd设置为最小值1,开启慢开始算法,降低传输效率
采用重传算法可以让发送方尽早知道发生个别网段丢失。
- 快重传使发送方尽快重传,而不等超时计时器超时再重传
- 接收方不要等待自己发送数据时才捎带确认,而要立即发送确认;即使收到了失序的报文段,也要立即发出对已收到的报文段的重复确认。
- 发送方一旦收到3个连续的重复确认(听好,我只说三遍),就将相应的报文段立即重传。而不等报文段的超时重传计时器超时再重传
- 对于个别丢失的报文段,发送方不会出现超时重传,也不会误认为出现拥塞(进而降低拥塞窗口cwnd为1)。使用快重传可以使整个网络吞吐量提高约20%
举例说明快重传算法
发送方 | 接收方 | |
第一轮 | 发送M1 | 接收M1,并且确认M1 |
第二轮 | 发送M2 | 接收M2,确认M2 |
第三轮 | 发送M3,中途丢失 | |
第四轮 | 发送M4, | 接收M4,但顺序不对,重复确认M2 |
第五轮 | 发送M5 | 接收M5,但顺序不对,重复确认M2 |
第六轮 | 发送M6 | 接收M6,但顺序不对,重复确认M2 |
第七轮 | 事不过三,开始重传M3 | 接收到M3,至此,1123456都收到了,则发送确认M6 |
快恢复算法
发送方一旦收到三个重复确认,就知道现在只是丢失个别报文段,不启动慢开始,而是执行快恢复算法。
- 发送方将ssthresh值和cwnd值调整为当前窗口一半,开始执行拥塞避免算法。
- 也有的快恢复实现是把快恢复开始时的cwnd再增大一些,即等于新的ssthresh + 3
理由如下:既然发送方收到3个重复确认,就表明三个数据报文段已离开网络
三个报文段不再消耗网络资源而是停留在接收方的接收缓存中
可见现在的网络中不是堆积了报文段而是减少了3个报文段,因此可适当把拥塞窗口扩大些
举例子:
TCP拥塞控制题目:
根据题意画一下拥塞窗口示意图
分析:刚开始是慢开始,后面是拥塞避免,然后到16发生碰撞。碰撞之后,ssthresh = 16/2,并执行慢开始算法,1,2,4,8,三个RTT(传输轮次),然后拥塞避免算法,一个轮次之后是9KB
超时后的4个RTT后 其实 就是4个传输轮次后
TCP重传时间选择
- 超时重传RTO的值应该略大于往返时间RTT
- RTO>>RTT,网络空间时间增大,降低传输效率
- RTO< RTT,引起报文段不必要的重传
怎么选择TRO呢?
- 不能直接使用测量的RTT样本作为RTO
- 但是可以测量每次的RTT值,计算加权平均值RTT(平滑的往返时间),
- 公式:RTTs1 = RTT,新的RTTs = (1-a)×旧的RTTs + a × 新的RTT样本(0≤a≤1)。
- 若a很接近于0,则新的RTT样本对RTTs的影响不大;a接近于1,则新的RTT样本对RTTs的影响较大。
- RFC推荐a=1/8,新的RTTs = 0.75×旧的RTTs + 0.25× 新的RTT样本(0≤a≤1)
- 这种方法比测量的值更加平滑
- 显然,RTO略大于RTTs
RTO的计算公式
RTO = RTTs + 4 × RTTd
上面的计算公式都是基于样本进行计算的,如果样本不正确,那么计算结果就不正确
情况如下
- 源主机将确认当做对原报文段的确认,计算的RTTs和RTO偏大,降低了传输效率
- 源主机误将确认当做是对重传报文段的确认,计算的RTTs 和 RTO会偏小,导致报文段没必要重传,增加网络负荷
针对超时重传无法测准往返时间RTT的问题,Karn提出算法,在计算加权平均往返时间时RTTs时,只要报文段重传了,就不采用其往返时间RTT样本,也就是出现重传,不重新计算RTTs,进而超时重传时间RTO也不会重新计算
这又引起了新问题,情况如下;时延突然变大,原来重传时间内,不会收到确认报文段,于是重传,根据Karn算法,不考虑样本,重传时间无法更新,导致报文段重复被重传。
对Karn算法修正:每重传一次,RTO增大一些,一般都是把RTO变为旧的的2倍
举例说明TCP超时重传时间的选择计算
总的公式计算过程如下:
按照上面的公式计算下面的情况:
解释RTO5为什么是这个?因为根据RTO4的值,判断应该穿过确认的时间没有传过来,说明超时了,那么就超时重传。
TCP可靠传输的实现
TCP以字节为单位的滑动窗口来实现可靠传输
TCP不赞成前沿向后收缩,因为这样很可能发送方在收到这个通知之前,就已经发送了窗口中的许多数据,现在又要收缩窗口,不让发送这些数据,显然就会产生错误。
发送窗口
有时候发送窗口的数据有一部分是发送但未收到确认,有一部分是允许发送但是还未发送的,如何描述发送窗口的状态,如何对发送窗口的状态进行标记和维护?
使用三个指针来进行维护
- <P1,已发送并已确认的部分
- ≥P3,不允许发送
- P3 - P1 = 当前发送窗口的尺寸
- P2 - P1 = 已发送 未确认 的字节数
- P3 - P2 = 允许发送但当前尚未发送的字节数(又称为可用窗口或有效窗口)
接收窗口
如果收到的不是按序到达的,则先存在缓存中
比如收到的是,34,37,39,但是33还没收到,所以给发送方发确认帧 33,意思是期望收到序号为33 的分组
补充说明
发送方的窗口根据接收方窗口设置,但是同一时刻并不总是和一样大。
- 因为接收方需要先告诉发送方自己的接收窗口多大,这个过程需要时间,即网络传送窗口值经历一定的时间滞后,并且时间不确定
- 发送方可能根据网络拥塞情况适当减小自己的窗口尺寸
对于不按序到达的数据如何处理,TCP并无明确规定
- 如何接收方把不按序列的数据一律丢弃,接收窗口管理较简单,但这样做网络资源的利用不利,因为发送方会重复传送较多的数据
- TCP通常对不按序到达的数据是先存放在接收窗口,等字节流中所缺少的字节收到后,再按序交付上层应用进程
TCP要求接收方必须累计确认和捎带确认机制,这样可以减小传输开销。接收方可以合适的时候发送确认,可以在自己有数据要发送时把确认信息顺带捎上。
- 接收方不应过分推迟发送确认,否则导致不必要的超时重传,浪费网络资源。TCP规定,确认推迟时间不应超过0.5s,若收到一连串具有最大长度的报文段,则必须每隔一个报文段就发送一个确认
- 捎带确认不经常发生
TCP的通信时全双工通信,通信的每一方都在发送接收报文段,因此每一方都有自己的发送窗口和接收窗口,在谈到这些窗口时,要弄清楚那一方的窗口。
TCP的运输连接管理——TCP的连接建立
- TCP 面向连接,基于运输连接来传送TCP报文段
- TCP运输连接的建立和释放是每一次面向连接的通信中必不可少的过程
- TCP运输连接有以下三个阶段
- 建立连接
- 数据传送
- 释放TCP连接
- TCP运输连接管理就是使运输连接的建立和释放都能正常的进行
TCP连接建立主要解决三个问题
- 使TCP双方都能确知对方的存在
- 使TCP双方能协商参数(如最大窗口值、是否使用窗口扩大选项和时间戳选项等)
- 使TCP双方能对运输实体资源(如缓存大小,链接表中的项目等)进行分配
TCP使用三报文握手建立连接
- TCP客户:主动发起TCP连接的
- TCP服务器:被动接收TCP连接请求的
过程
- 最初,两端的TCP都处于关闭状态
- TCP服务器进程首先创建传输控制块,准备接收客户连接请求(进入监听状态),因为是被动进行这一系列的准备的,所以称为被动打开
- TCP客户进程也创建传输控制块,发送TCP连接请求报文段(进入同步已发送状态),称为主动打开连接
TCP连接请求报文段首部中:
同步位SYN = 1,表明这是一个连接请求报文,
序号字段seq = x,作为TCP客户进程所选择的初始序号
TCP规定:SYN = 1 的报文段不携带数据,但要消耗掉一个序号
- 服务器收到请求,同意连接,则发送TCP连接请求确认报文段(进入同步已接收状态)
SYN=1,ACK=1:这是一个TCP连接请求确认报文段
seq=y:初始值,作为TCP服务器进程所选择的初始序号
ack=x+1:对TCP客户进程所选择的初始序号的确认
也不能携带数据,但是消耗掉一个序号
- 接到确认之后,发送针对TCP连接请求的发送一个普通的TCP确认报文段(连接已建立状态)
ACK=1:这是一个普通的TCP确认字段
seq=x+1:客户进程第一个序号为x,不携带数据,第二个设为x+1
ack=y+1:对上面服务进程所选择的初始序号的确认
TCP普通的确认报文段可以携带数据,但是如果不携带数据,不消耗序号
- 服务器收到后,也成为了连接已建立状态,两个都是连接已建立状态,则可以进行数据传输了
为什么TCP客户进程最后还要发送一个普通的TCP确认报文段呢?是否多余呢?
答:不多余,不能简化为两报文握手。
情况:TCP连接请求超时重传
TCP的运输连接管理——TCP的连接释放
通过四报文挥手来释放连接
- FIN=1,ACK=1:表明这是一个TCP释放报文段,同时也对之前收到的 报文段进行确
- 只有ACK=1,表明是一个普通的TCP确认报文段
- seq=u:u = TCP客户进程之前已传送过的数据的最后一个字节的序号 + 1
- ack=v:等于TCP客户进程之前已收到的数据的最后一个字节序号+1
- TCP规定:终止位FIN = 1的报文段即使不携带数据,也要消耗掉一个序号
数据传输完成后,通信双方都可以释放连接,假设使用TCP客户进程的应用进程通知其主动关闭TCP连接,过程如下:
TCP客户端 | TCP服务端 | |
第一回合 客户→服务 服务→客户 结束后,TCP连接为半关闭状态 也就是TCP客户进程没有数据发送了,因为服务端已经关闭了 但是如果服务器要给客户端发数据,其实还是可接收的 | 连接释放报文: FIN=1,ACK=1 seq=u ack=v 进入了终止等待状态 | 收到连接释放报文 ACK=1 seq=v ack=u+1 进入关闭等待状态 客户到服务器这个方向的连接释放了 |
第二回合 服务→客户 | 收到确认报文,进入终止等待2状态,等待TCP服务进程发出的TCP | FIN = 1 ACK = 1 seq = w(可能又发生了一些数据) ack =u + 1(对连接释放的重复确认) 进入最后确认状态 |
第三个回合 客户→服务 | 接收到之后, ACK=1 seq = u +1 ack = w + 1 进入时间等待状态 | 收到后,进入关闭状态 |
第三个回合 没有发送 | 等待2MSL之后,进入关闭状态 MSL:最长报文寿命,建议为2mins |
为什么要进入等待状态等待2SML才进入到关闭状态呢?能不能直接进入关闭状态?
加入服务器端进入最后确认状态之后,TCP收到报文,发送普通确认报文段,并进入关闭状态。但是普通报文段丢失了,则TCP超时重传,但是客户端关闭无法理睬,那么服务器只能一直重传了。
TCP中保活计时器的作用:
如果TCP客户出现故障,TCP服务器不应该白白等待,应该如何去发现这种情况呢?
- TCP服务器每收到一次TCP客户进程的数据,就重新设置并启动保活计时器(2小时定时)
- 保活计时器定时周期内未收到TCP客户数据,则当保护计时器到时后,TCP服务器进程就向TCP客户进程发送一个探测报文段,以后每隔75s发送一次,若连续10个探测都无响应,则判断其出现故障,接着关闭连接。
TCP报文段的首部格式
TCP的全部功能体现在它的首部各个字段的作用
- 源端口: 16bit,用来标识发送该 TCP 报文段 的应用进程
- 目的端口:16bit, 用来标识发送该 TCP 报文段 的应用进程
- 序号:32bit,序号增加到最后一个后,下一个序号就回到0。指出本TCP报文段数据载荷的第一个字节的序号
- 确认号:32bit,增加到最后一个后,下一个确认号就又回到0。指出期望收到对方下一个报文段的第一个字节的序号,同时也是对之前收到的所有数据的确认。若确认号 = n,则n-1已经全部接收
- 数据偏移:4bit,以四字节为单位,TCP报文段的数据载荷部分距离TCP报文的起始处多远。指出了TCP报文段的首部长度。
- 保留:6bit,保留今后使用
- URG:取值=1,紧急指针有效,=0,紧急指针无效
- ACK:取值为1,确认段有效,否则,无效。TCP规定,连接建立后,所有传送的TCP报文段都必须把ACK 置为1.
- PSH:推送标志位,接收方PSH=1,会尽快上交应用进程,而不必等到接收缓存都填满后再交付
- RST:用来复位TCP连接。当RST = 1的功能:① 表明TCP连接出现异常,必须释放连接,然后再重新建立连接 ②RST置1还用来拒绝一个非法的报文段或者拒绝打开一个TCP连接
- SYN:TCP建立时用来同步序号,表明TCP连接请求,如果ACK=1,说明是TCP连接确认报文段
- FIN:释放TCP连接
- 窗口:占16bit,以字节为单位,指出发送本报文的一方的接收窗口。以接收方的接受能力来控制发送方的发送能力,称为流量控制。应该去min(接收窗口,拥塞窗口)
- 检验和:16bit,检查范围包括TCP首部 数据载荷两部分。在计算校验和时,要在TCP报文段的前面加上12字节的伪首部。
- 紧急指针:占16bit,以字节为单位,用来指明紧急数据的长度。发送方有紧急数据时,可将紧急数据插队到发送缓存的最前面,并立刻封装到TCP报文中,紧急指针指出本报文段数据载荷部分包含了多长的紧急数据,紧急数据之后是普通数据。
- 选项(长度可变):增加TCP的功能,有以下选项:最大报文段长度MSS选项(TCP数据载荷的最大长度),窗口扩大选项(提高吞吐率),时间戳选项(用来计算往返时间RTT,或者处理超范围情况,又称为序号绕回PAWS),选择确认选项(选择选择确认功能)
- 填充:确保报文首部被4整除