学习笔记_UDP的可靠传输协议QUIC

学习笔记_UDP的可靠传输协议QUIC

UDP可靠性设计,解决的是数据实时性问题,流速问题

如何做到可靠性传输

  • ACK机制
    确保对方应答
  • 重传机制
    定时机制,重传策略
  • 序号机制 3 2 1 ->2 3 1
    对包进行编号
  • 重排机制 2 3 1 -> 3 2 1
    根据包的序号进行重排,不是当前的先进行缓存
  • 窗口机制
    发送数据给对方,当时对方一直收,导致我的发送缓存区满了

UDP和TCP的区别

UDP每一次必须一次读完,没读完的就丢掉了

选项UDPTCP
是否连接无连接面向连接
是否可靠不可靠传输,不使用流量控制和拥塞控制可靠传输,使用流量控制和拥塞控制
连接对象个数支持一对一,一对多,多对一和多,对多交互通信只能是一对一通信
传输方式面向报文面向字节流
首部开销首部开销小,仅8字节首部最小20字节,最大60字节
适用场景适用于实时应用(IP电话、视频会议、直播等)游戏行业、物联网行业适用于要求可靠传输的应用,例如文件传输

UDP和TCP的格式对比

|16位端口号|16位目标端口|
|16长度|16位校验和|
|数据|

滑动窗口

滑动窗口 发送方和接受方都会维护一个数据帧的序列,这个序列被称作窗口,发送方的窗口大小由接收方确定。目的在于控制发送速度,避免接收方缓存不够大,导致溢出,同时控制流量也可以避免网络拥塞。协议中规定,对于窗口内未经确认的分组需要重传。

  1. 接收数据的为接收窗口,发送数据的为拥塞窗口(发送窗口),指出窗口大小的通知称为窗口通告
  2. 窗口大小通过某种算法动态调整
  3. 窗口增大会消耗内存,其大小需要根据网络环境以及发送方的拥塞窗口来动态调整。
  4. 一般情况下接收窗口>=发送窗口,发送窗口通过接收窗口动态进行调整

ARQ协议(Automatic Repeat-reQuest)

主要是以下三种模式:

  1. 即停等式(stop-and-wait)ARQ
    发送方发送数据包,然后等待接收方回复ACK并且开始及时
    再等待ack的过程中不会发送新的数据包
    当数据包没有成功被接收方接受,接收方不会回复ack,发送方等待到超时时间后重新发送数包
    反复以上步骤直到收到ack

  2. 回退n帧(go-back-n)ARQ -->GBN协议
    回退N步(Go-Back-N,GBN) 回退N步协议允许发送方在等待超时的间歇,可以继续发送分
    组。所有发送的分组,都带有序号。在GBN协议中,发送方需响应以下三种事件:
    1、上层的调用。上层调用相应send()时,发送方首先要检查发送窗口是否已满。
    2、接收ACK。在该协议中,对序号为n的分组的确认采取累积确认的方式,表明接收方已正确接收到序号n以前(包括n)的所有分组。
    3、超时。若出现超时,发送方将重传所有已发出但还未被确认的分组
    对于接收方来说,若一个序号为n的分组被正确接收,并且按序,则接收方会为该分组返回一个ACK给发送方,并将该分组中的数据交付给上层。在其他情况下,接收方都会丢弃分组。若分组n已接收并交付,那么所有序号比n小的分组也已完成了交付。因此GBN采用累积确认是一个很自然的选择。发送方在发完一个窗口里的所有分组后,会检查最大的有效确认,然后从最大有效确认的后一个分组开始重传。
    注意 若序号2的分组丢失,则2和之后的分组都将重传

  3. 选择性重传(selective repeat)ARQ,SR协议

    在SR协议下,发送方需响应以下三种事件:
    1、从上层收到数据。当从上层收到数据后,发送方需检查下一个可用于该分组的序号。若序号在窗口中则将数据发送。
    2、接收ACK。若收到ACK,且该分组在窗口内,则发送方将那个被确认的分组标记为已接收。若该分组序号等于基序号,则窗口序号向前移动到具有最小序号的未确认分组处。若窗口移动后并且有序号落在窗口内的未发送分组,则发送这些分组。
    3、超时。若出现超时,发送方将重传已发出但还未确认的分组。与GBN不同的是,SR协议中的每个分组都有独立的计时器

    在SR协议下,接收方需响应以下三种事件:
    (假设接收窗口的基序号为4,分组长度也为4)
    1、序号在[4,7]内的分组被正确接收。该情况下,收到的分组落在接收方的窗口内,一个ACK将发送给发送方。若该分组是以前没收到的分组,则被缓存。若该分组的序号等于基序号4,则该分组以及以前缓存的序号连续的分组都交付给上层,然后,接收窗口将向前移动。
    2、序号在[0,3]内的分组被正确接收。在该情况下,必须产生一个ACK,尽管该分组是接收方以前已确认过的分组。若接收方不确认该分组,发送方窗口将不能向前移动。
    3、其他情况。忽略该分组对于接收方来说,若一个分组正确接收而不管其是否按序,则接收方会为该分组返回一个ACK给发送方。失序的分组将被缓存,直到所有丢失的分组都被收到,这时才可以将一批分组按序交付给上层。

RTT和RTO

RTO(Retransmission TimeOut)即重传超时时间。如果RTT=200ms,则重传时间为400ms
RTT(Round-Trip Time): 往返时延。表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认),总共经历的时延。
◼ 链路的传播时间(propagation delay)
◼ 末端系统的处理时间、
◼ 路由器缓存中的排队和处理时间(queuing delay)

流量控制————与接收方的缓存状态相关联

流量控制————对发送方发送速率的控制

  • 双方通信,如果发送方的速率大于接收方,接收方处理不来会将数据放到缓存中
  • 如果缓存满了,发送方还在发送数据,接受方只能将数据包丢掉,所以需要控制发送速率,让两者处于动态平衡

流量控制————如何控制?发送方根据接收方的窗口大小控制自己的发送窗口大小

接收方每次收到数据包后,再返回确认报文得同时告诉发送方自己得缓存区还剩余多少空闲,我们也把缓存区得剩余大小称之为接收窗口大小,用变量win来表示接收窗口的大小。
发送方收到之后,便会调整自己的发送速率,也就是调整自己发送窗口的大小,当发送方收到接收窗口的大小为0时,发送方就会停止发送数据,防止出现大量丢包情况的发生。

流量控制————发送方何时再继续发送数据?

  1. 当接收方处理好数据后,接收窗口win>0,接收方发个通知报文去通知发送方
  2. 当发送方收到接受窗口 win = 0 时,这时发送方停止发送报文,并且同时开启一个定时器,每隔一段时间就发个测试报文去询问接收方,打听是否可以继续发送数据了,如果可以,接收方就告诉他此时接受窗口的大小;如果接受窗口大小还是为0,则发送方再次刷新启动定时器。

拥塞控制————与网络的拥堵情况相关联

为什么需要?

A发送给B数据,A却没有手动B的ACK,而造成这个的原因却是因为太多主机正在使用信道资源,导致网络拥塞了,而A发送的数据被堵在路上没有到达B。但这个时候A却以为丢包了然后进行重传,这样子只会让网络更加拥塞。

拥塞窗口探测过程

A和B建立连接,刚开始A并不知道网络的拥塞情况,需要进行探测,而我们将A一次性能够发送多少个数据包称之为 拥塞窗口
探测过程 通过不断尝试发送数量递增的包,直到出现超时。设置一个阈值,如8,刚开始指数增长1,2,4,8,之后再进行线性增长9,10,11,12…,假如增加到14后出现超时事件,则将14称为 瓶颈值。之后回到最初状态,并设置阈值为瓶颈值/2=14/2=7,然后继续

超时不一定是网络拥塞,所以还需要通过冗余ack来辨别

超时也可以是包丢失或损坏

为了防止这种情况,我们是通过冗余ACK来处理的。我们都知道,数据包是有序号的,如果A给B发送M1, M2, M3, M4, M5…N个数据包,如果B收到了M1, M2, M4…却始终没有收到M3,这个时候就会重复确认M2,意在告诉A,M3还没收到,可能是丢失了。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5pEjPXbn-1644536379251)(./resource/image/tcp_reno.png)]
当A连续收到了三个确认M2的ACK,且M3超时事件还没发生。A就知道M3可能丢失了,这个时候A就不必等待M3设置的计时器到期了,而是 快速重传M3。并且把ssthresh设置为MAX的一半,即ssthresh = MAX/2,但是这个时候并非把控制窗口N设置为1,而是让N = ssthresh,N在一个一个增长

慢启动和快恢复

KCP

TCP是为流量设计的(每秒内可以传输多少KB的数据),讲究的是充分利用带宽。而 KCP是为流速设计的(单个数据包从一端发送到一端需要多少时间),以10%-20%带宽浪费的代价换取了比 TCP快30%-40%的传输速度。TCP信道是一条流速很慢,但每秒流量很大的大运河,而KCP是水流湍急的小激流。KCP有正常模式和快速模式两种,通过以下策略达到提高流速的结果:

RTO翻倍vs不翻倍:(Retransmission TimeOut)即重传超时时间
TCP超时计算是RTOx2,这样连续丢三次包就变成RTOx8了,十分恐怖,而KCP启动快速模式后不x2,只是x1.5(实验证明1.5这个值相对比较好),提高了传输速度。

选择性重传 vs 全部重传:
TCP丢包时会全部重传从丢的那个包开始以后的数据,KCP是选择性重传,只重传真正丢失的数据包。

快速重传:
发送端发送了1,2,3,4,5几个包,然后收到远端的ACK: 1, 3, 4, 5,当收到ACK3时,KCP知道2被跳过1次,收到ACK4时,知道2被跳过了2次,此时可以认为2号丢失,不用等超时,直接重传2号包,大大改善了丢包时的传输速度。

延迟ACK vs 非延迟ACK:
TCP为了充分利用带宽,延迟发送ACK(NODELAY都没用),这样超时计算会算出较大 RTT时间,延长了丢包时的判断过程。KCP的ACK是否延迟发送可以调节。

UNA vs ACK+UNA:
ARQ模型响应有两种,UNA(此编号前所有包已收到,如TCP)和ACK(该编号包已收到),光用UNA将导致全部重传,光用ACK则丢失成本太高,以往协议都是二选其一,而 KCP协议中,除去单独的 ACK包外,所有包都有UNA信息。

非退让流控:
KCP正常模式同TCP一样使用公平退让法则,即发送窗口大小由:发送缓存大小、接收端剩余接收缓存大小、丢包退让及慢启动这四要素决定。但传送及时性要求很高的小数据时,可选择通过配置跳过后两步,仅用前两项来控制发送频率。以牺牲部分公平性及带宽利用率之代价,换取了开着BT都能流畅传输的效果。

名词说明

用户数据:应用层发送的数据,如一张图片2Kb的数据
MTU:最大传输单元。即每次发送的最大数据
RTO:Retransmission TimeOut,重传超时时间。
cwnd:congestion window,拥塞窗口,表示发送方可发送多少个KCP数据包。与接收方窗口有关,与网络状况(拥塞控制)有关,与发送窗口大小有关。
rwnd:receiver window,接收方窗口大小,表示接收方还可接收多少个KCP数据包
snd_queue:待发送KCP数据包队列,被snd_nxt取到后释放
snd_nxt:下一个即将发送的kcp数据包序列号,收到ack后释放
snd_una:下一个待确认的序列号
recv_buf:最先收到数据
recv_queue:靠近用户,将recv_buf中排行徐的放到这里

使用方式

  1. 创建 KCP对象:ikcpcb *kcp = ikcp_create(conv, user);
  2. 设置传输回调函数(如UDP的send函数):kcp->output = udp_output;
    1. 真正发送数据需要调用sendto
  3. 循环调用 update:ikcp_update(kcp, millisec);
  4. 输入一个应用层数据包(如UDP收到的数据包):
    ikcp_input(kcp,received_udp_packet,received_udp_size);
    1. 我们要使用recvfrom接收,然后扔到kcp里面做解析
  5. 发送数据:ikcp_send(kcp1, buffer, 8); 用户层接口
  6. 接收数据:hr = ikcp_recv(kcp2, buffer, 10);

发送窗口和接收窗口

  1. 发送窗口有最大值,默认是32个分片(IKCPSEG)
  2. 发送窗口又是变动的

命令

IKCP_CMD_PUSH:普通用户数据包
IKCP_CMD_ACK:应答分片
IKCP_CMD_WASK:窗口询问
IKCP_CMD_WINS:回复窗口大小

用户数据

一个UDP包中有一个或多个segment,segment包括header(24)+Data(…),kcp内部将用户数据划分为多个segment,再把segment封装到udp报文中
每个ack都是独立的segment

自己编写回调函数

发送数据到内核
从内核接收数据

QUIC协议,Quick UDP Internet Connections,谷歌发明的新传输协议

  • 主要目的 为了整合tcp协议的可靠性和udp协议的速度和效率。
  • QUIC可以在1到2个数据包内完成连接的建立(取决于连接的服务器是新的还是已知的),包括TLS
  • QUIC 非常类似于在 UDP 上实现的 TCP + TLS + HTTP/2
  • 是在用户态基于udp实现的传输层
  • 为什么不再内核统一级别quic、tcp、udp?
    1. quic还是一个草案,还在更新
    2. 放在内核影响大,所有系统都要更新
    3. 路由器,还有很多中间设备、防火墙也要改动
      1)小地方,路由封杀UDP 443端口( 这正是QUIC 部署的端口);
      2)UDP包过多,由于QS限定,会被服务商误认为是攻击,UDP包被丢弃;
      3)无论是路由器还是防火墙目前对QUIC都还没有做好准备。
  • QUIC 与现有 TCP + TLS + HTTP/2 方案相比,有以下几点主要特征:
    1. 利用缓存,显著减少连接建立时间;
    2. 改善拥塞控制,拥塞控制从内核空间到用户空间;
    3. 没有 head of line 阻塞的多路复用;
    4. 前向纠错,减少重传;
    5. 连接平滑迁移,网络状态的变更不会影响连接断线。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QUICQuick UDP Internet Connections)是基于UDP协议的一种传输协议。它是一种用于提供安全且快速的互联网连接的协议。与TCP相比,QUIC具有更低的连接延迟和更好的网络拥塞控制能力。QUIC协议将数据包分为Header和Data两部分,其中Header包含了一些关键信息,如Frame Type,用于标识不同类型的数据包,如Stream、ACK、Padding、Blocked等。 QUIC协议的实现有许多版本和变种,其中QuicNet是QUIC协议的.NET实现。它与quic-transport草案的第32版保持一致,并且还未提供其他相关草案的实现,如quic-tls和快速恢复。 在数据传输方面,QUIC协议和TCP一样利用滑动窗口机制来实现流量控制。当发送端收到接收端的ACK帧时,窗口会向右滑动,从而发送新的数据包。不过,与TCP不同的是,QUIC协议具有更好的拥塞控制和流量控制能力,可以更有效地管理网络中的数据传输。 综上所述,QUIC是一种基于UDP传输协议,用于提供安全且快速的互联网连接。它具有低延迟和优秀的拥塞控制能力,并采用滑动窗口机制实现流量控制。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [QUIC协议详解](https://blog.csdn.net/weixin_41821317/article/details/122993082)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Quic.NET:QUIC协议的.NET C#实现-Google的实验性传输层](https://download.csdn.net/download/weixin_42127775/18481734)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值