快速UDP网络连接之QUIC协议介绍

文章目录

  • 一、QUIC协议历史
    • 1.1 问题:QUIC为什么在应用层实现
    • 1.2 QUIC协议相关术语
    • 1.3 QUIC和TCP对比
    • 1.4 QUIC报文格式
      • 1.4.1 QUIC报文格式-Stream帧1
      • 1.4.2 QUIC报文格式-Stream帧2
  • 二、QUIC的特点
    • 2.1 连接建立低时延,
    • 2.2 多路复用
      • 流复用-HTTP1.1
      • 流复用-HTTP2
      • 流复用-HTTP3(QUIC)
    • 2.3 无队头阻塞
    • 2.4 灵活的拥塞控制机制
    • 2.5 连接迁移
      • 连接迁移1
      • 连接迁移2
    • 2.6 数据包头和包内数据的身份认证和加密
    • 2.7 FEC前向纠错
    • 2.8 可靠性传输
      • 问题 1:发送端怎么知道发出的包是否被接收端收到了?
      • 问题 2:既然包号是单调递增的,那接收端怎么保证数据的有序性呢?
    • 2.9 带宽优化
  • 三、QUIC开源库和应用
  • 四、QUIC面临的挑战


一、QUIC协议历史

  QUIC(Quick UDP Internet Connections)即 快速UDP网络连接,是由Google开发的基于UDP的传输层网络协议。QUIC的设计目标是提高网络应用程序的性能和可靠性,特别是在高延迟和不稳定网络环境下。

  quic文档地址:https://quicwg.org/base-drafts/rfc9000.html

  quic架构图:
在这里插入图片描述

1.1 问题:QUIC为什么在应用层实现

  新的传输层协议通常会经过严格的设计,分析和评估可重复的结果,证明候选协议对 现有协议的正确性和公平性,开发新的传输层协议和它在操作系统进行广泛部署之间 通常需要花费数年的时间。
  再者,用户与服务器之间要经过许多防火墙、NAT(地址转换)、路由器和其他中间设 备,这些设备很多只认TCP和UDP。如果使用另一种传输层协议,那么就会有可能无法 建立连接或者报文无法转发,这些中间设备会认为除TCP和UDP协议以外的协议都是不 安全或者有问题的。

1.2 QUIC协议相关术语

● QUIC连接:Client和Server之间的通信关心,Client发起连接,Server接受连接
● 流(Stream):一个QUIC连接内,单向或者双向的有序字节流。一个QUIC连 接可以同时包含多个Stream
● 帧(Frame):QUIC连接内的最小通信单元。一个QUIC数据包(packet)中的 数据部分包含一个或多个帧

1.3 QUIC和TCP对比

在这里插入图片描述
  ORTT 指的是“Operation Round-Trip Time”(操作往返时间)。这通常是指在计算机网络中,一个数据包从发送端发出,到达接收端并得到响应,然后返回到发送端所需的总时间。这是一个关键的性能指标,因为它可以反映网络的延迟和响应能力。

ORTT的关键点包括:

  1. 延迟(Latency):这是数据从发送端到达接收端所需的时间。延迟可能受到物理距离、网络设备处理时间和传输介质等因素的影响。
  2. 处理时间(Processing Time):接收端处理数据包并生成响应所需的时间。这包括服务器处理请求的时间。
  3. 往返时间(Round-Trip Time, RTT):这是数据包从发送端发送,到达接收端并得到响应,然后返回到发送端的总时间。RTT 包括了延迟和处理时间。

如何测量ORTT:

  1. Ping命令:这是最常用的测量RTT的工具。Ping命令向目标主机发送ICMP ECHO请求,并计算从发送请求到接收响应所用的时间。
  2. Traceroute命令:Traceroute工具不仅测量RTT,还显示数据包经过的每一跳路由器的RTT,从而帮助识别网络路径中的延迟来源。
  3. 网络性能监测工具:如Wireshark、Nagios、Zabbix等,可以提供更详细的ORTT分析和报告。

优化ORTT的方法:

  1. 优化网络路径:通过选择更短或更高效的网络路径来减少延迟。
  2. 减少服务器处理时间:提高服务器性能,优化应用程序代码,以减少处理请求的时间。
  3. 使用内容分发网络(CDN):通过在地理上分布的服务器缓存内容,减少物理距离带来的延迟。
  4. 网络协议优化:使用更高效的通信协议,如HTTP/2、QUIC等,可以减少往返次数和时间。

  理解和优化ORTT对于提高网络应用的性能和用户体验至关重要。

1.4 QUIC报文格式

  一个 QUIC 数据包的格式
在这里插入图片描述

● Header 是明文的,包含 4 个字段:Flags、Connection ID、QUIC Version、Packet Number;
● Data 是加密的,可以包含 1 个或多个 frame,每个 frame 又分为 type 和 payload, 其中 payload 就是应用数据

1.4.1 QUIC报文格式-Stream帧1

  数据帧有很多类型:Stream、ACK、Padding、Window_Update、Blocked 等,这里重点介 绍下用于传输应用数据的 Stream 帧。
在这里插入图片描述

Frame Type: 帧类型,占用 1 个字节
在这里插入图片描述

(1)Bit7:必须设置为 1,表示 Stream 帧,一个udp通道可以发送多个流
(2)Bit6:如果设置为 1,表示发送端在这个 stream 上已经结束发送数据,流将处于半关闭状态
(3)Bit5:如果设置为 1,表示 Stream 头中包含 Data length 字段
(4)Bit432:表示 offset 的长度。000 表示 0 字节,001 表示 2 字节,010 表示 3 字节,以此类推
(5)Bit10:表示 Stream ID 的长度。00 表示 1 字节,01 表示 2 字节,10 表示 3 字节,11 表示 4 字 节

1.4.2 QUIC报文格式-Stream帧2

在这里插入图片描述

Stream ID:流 ID,用于标识数据包所属的流。后面的流量控制和多路复用会涉及到。
Offset:偏移量,表示该数据包在整个数据中的偏移量,用于数据排序。
Data Length: 数据长度,占用 2 个字节,表示实际应用数据的长度 Data: 实际的应用数据。

二、QUIC的特点

2.1 连接建立低时延,

典型TCP+TLS连接
在这里插入图片描述

1.首先,执行三次握手,建立 TCP 连接(蓝色部分);
2.然后,执行 TLS 握手,建立 TLS 连接(黄色部分);
3.此后开始传输业务数据;
客户端和服务器之间要进行多轮协议交互,才能建立 TLS 连接,延迟相当严重。 平时访问 https 网站明显比 http 网站慢,三次握手和 TLS 握手难辞其咎。

QUIC首次连接
在这里插入图片描述

● 共3RTT:TCP+TLS1.2中: TCP三次握手建立连接需要1个RTT;TLS需要2个RTT完成 身份验证;传输数据
● 共2RTT:TCP+TLS1.3中: TCP三次握手建立连接需要1个RTT;TLS需要1个RTT完成 身份验证;传输数据
● 共1RTT: 首次QUIC连接中,Client 向 Server 发送消息,请求传输配置参数和加 密相关参数;Server 回复其配置参数;传输数据

注解:
注意到,三次握手中的 ACK 包与 handshake 合并在一起发送。 这是 TCP 实现中使用的 延迟确认 技术, 旨在减少协议开销,改善网络性能。
QUIC再次连接
在这里插入图片描述

● 再次连接的概念:Client已经访问过Server,在本地存放了Cookie。
● 2RTT:TCP+TLS1.2中: TCP三次握手建立连接需要1个RTT;TLS需要1个RTT完成身份 验证(由于缓存的存在,减少1RTT);传输数据
● 1RTT:TCP+TLS1.3 中: TCP三次握手建立连接需要1个RTT;传输数据
● 0RTT:在客户端与服务端的再次QUIC连接中,Client 本地已有 Server 的全部配置 参数(缓存),据此计算出初始密钥,直接发送加密的数据包。

2.2 多路复用

  在一个网页里面总是会有多个数据要传输,总是希望多个数据能够同时传输,以此 来提高用户的体验。
在这里插入图片描述

流复用-HTTP1.1

在这里插入图片描述

在HTTP1.1中:
● 每个TCP连接同时只能处理一个请求—响应,为了提高响应速度,需要 同时创建多个连接,但是多个连接管理比较复杂

流复用-HTTP2

在这里插入图片描述

在HTTP2中:
● 每个TCP连接里面有多个逻辑上独立的多个流(stream)
● 每个流可以传输不同的文件数据
● 解决了HTTP1一个连接无法同时传输多个数据的问题
● 缺点:容易出现队头阻塞问题

流复用-HTTP3(QUIC)

在这里插入图片描述

而在基于QUIC的HTTP3中:
● 借鉴了HTTP2中流的概念
● 流 之 间 互 相 独 立 , 即 不 同 流 之 间 的 数 据 之 间 交 付 顺 序 无 关 ( 如果 stream2的数据丢失,只会影响排在stream2后面的数据,stream1和 stream3的数据不会被影响)
● 建立在UDP之上,没有依赖性

2.3 无队头阻塞

  HTTP/2会出现队头阻塞问题,而在基于QUIC的HTTP/3中则很好地解决这一问题.
在这里插入图片描述

  UDP中的各个数据报独立,基于UDP的QUIC中的各个stream独立
即使stream2里有一个包丢失,因为stream之间互相独立无关联,所以不会 阻塞stream3、stream4,依然可以交付给上层

2.4 灵活的拥塞控制机制

  TCP 的拥塞控制实际上包含了四个算法:慢启动,拥塞避免,快速重传,快 速恢复
(1)New Reno:基于丢包检测
(2)CUBIC:基于丢包检测
(3)BBR:基于网络带宽 可以自己去设置拥塞控制机制,也可以自己去实现拥 塞控制协议
  QUIC 协议当前默认使用了 TCP 协议的 Cubic 拥塞控制算法。
这个机制还是可插拔的,什么叫可插拔呢?就是能够非常灵活地生效,变 更和停止,可以根据场景来切换不同的方法。
  QUIC协议在用户空间实现,应用程序不需要停机和升级就能实现拥塞控制 的变更,在服务端只需要修改一下配置,reload 一下,完全不需要停止服务 就能实现拥塞控制的切换。甚至可以为每一个请求都设置一种拥塞控制算法。
  而TCP在内核态,其拥塞控制难以进行修改和升级。

2.5 连接迁移

连接迁移1

场景:

  1. 使用WIFI上网的时候突然网络不好,于是切换成移动数据模式;又或者没有流量上 不了网,于是连接WIFI
  2. 户外4G基站的切换,比如在做地铁时正在语音通话,不同的站点会切换不同的基站。 对于5G基站则切换更为频繁。

  连接迁移:当客户端切换网络时,和服务器的连接并不会断开,仍然可以正常通信, 对于 TCP 协议而言,这是不可能做到的。因为 TCP 的连接基于 4 元组:源 IP、源端口、 目的 IP、目的端口,只要其中 1 个发生变化,就需要重新建立连接。但 QUIC 的连接是 基于 64 位的 Connection ID,网络切换并不会影响 Connection ID 的变化,连接在逻辑上 仍然是通的。
  IP地址或者端口号发生变化时,只要ID不变,依然能够维持原有连接,上层业务逻辑感 知不到变化,不会中断。

连接迁移2

在这里插入图片描述

  假设客户端先使用 IP1 发送了 1 和 2 数据包,之后切换网络,IP 变更为 IP2,发送了 3 和 4 数据包,服务器根据数据包头部的 Connection ID 字段可以判断这 4 个包是来自于同一 个客户端。QUIC 能实现连接迁移的根本原因是底层使用 UDP 协议就是面向无连接的。

2.6 数据包头和包内数据的身份认证和加密

  相比于TCP,QUIC的安全性是内置的,也就是说是必须的。
在恶意环境下性能与TLS类似,友好环境下优于TLS,因为TLS使用一个会话密钥, 如果这个密钥被截获的话就不能保证之前数据的安全性。
而QUIC使用两个密钥——初始密钥和会话密钥,并且QUIC提供密码保护,TLS不提供。
  除此之外,QUIC的包头经过身份认证,包内数据是加密的。这样如果QUIC数据 被恶意修改的话接收端是可以发现的,降低了安全风险。
  而且数据加密之后,可以通过像防火墙或者nat这些中间件。

2.7 FEC前向纠错

  FEC是Forward Error Correction前向错误纠正的意思,就是通过多发一些冗余的包, 当有些包丢失时,可以通过冗余的包恢复出来,而不用重传。这个算法在多媒 体网关拥塞控制有重要的地位。QUIC的FEC是使用的XOR的方式,即发N + 1个包, 多发一个冗余的包,在正常数据的N个包里面任意一个包丢了,可以通过这个冗 余的包恢复出来,使用异或可以做到切换网络操持连接。
  1 2 3 4,重新编码 出来 5 4 3 2 1 -> 5 4 3 2 -> 4 3 2 1

2.8 可靠性传输

  QUIC 是基于 UDP 协议的,而 UDP 是不可靠传输协议,那 QUIC 是如何实现可靠传输的呢? 可靠传输有 2 个重要特点:
(1)完整性:发送端发出的数据包,接收端都能收到
(2)有序性:接收端能按序组装数据包,解码得到有效的数据

问题 1:发送端怎么知道发出的包是否被接收端收到了?

解决方案:通过包号(PKN)和确认应答(SACK)
在这里插入图片描述

(1)客户端:发送 3 个数据包给服务器(PKN = 1, 2,3)
(2)服务器:通过 SACK 告知客户端已经收到了 1 和 3,没有收到 2
(3)客户端:重传第 2 个数据包(PKN=4) 由此可以看出,QUIC 的数据包号是单调递增的。 也就是说,之前发送的数据包(PKN=2)和重传的 数据包(PKN=4),虽然数据一样,但包号不同。

问题 2:既然包号是单调递增的,那接收端怎么保证数据的有序性呢?

解决方案:通过数据偏移量 offset
每个数据包都有一个 offset 字段,表示在整个数据中的偏移量。
在这里插入图片描述

接收端根据 offset 字段就可以对异步到达的数据包进行排 序了。为什么 QUIC 要将 PKN 设计为单调递增?解决 TCP 的重传歧义问题:
由于原始包和重传包的序列号是一样的,客户端不知道服 务器返回的 ACK 包到底是原始包的,还是重传包的。但 QUIC 的原始包和重传包的序列号是不同的,也就可以判 断 ACK 包的归属。

2.9 带宽优化

  QUIC协议对带宽使用进行了优化,通过更高效的ACK机制和流控算法,减少了不必要的数据传输和重复确认。

  QUIC最初由Google在其自家服务中使用,并且已经成为HTTP/3的基础。HTTP/3是HTTP协议的最新版本,旨在利用QUIC的优势来提高网页加载速度和用户体验。

  QUIC协议已经得到了广泛的支持和应用,许多现代浏览器(如Google Chrome、Mozilla Firefox)和服务器(如NGINX)都已经实现了对QUIC的支持。

  QUIC协议通过结合UDP的低延迟和TCP的可靠性,为现代互联网应用提供了一种高效、安全的传输方案。

三、QUIC开源库和应用

  1. google的gquic 起源最早, 不过它不是单独项目, 代码在chromium项目里边, 用的 是c++写的, 可能不是很适合.
  2. 微软的msquic, 用c写的, 跨平台, 不过开始得比较晚(好像2020才开始, 不是很成 熟).
  3. facebook的quic 用的是c++写的. 暂不考虑.
  4. nginx的quic 没有自带client, 但它可与ngtcp2联调.
  5. litespeed的 lsquic 是基于MIT的, 开始于2017年, 还算比较稳定, 用c语言编写, 各 主流平台都有通过测试, 有server/client/lib, 它用于自家的各种产品, 暂时看上去 是最合适的.
  6. ngtcp2, 它是一个实验性质的quic client, 很简洁, 实现了几乎每一版ietf draft. 从 代码简洁性上来看, 它无疑是最好的。目前srs流媒体服务器、curl等开源项目有 基于ngtcp2做二次开发。

  ngtcp2 仓库 https://github.com/ngtcp2/ngtcp2,ngtcp2采用c语言实现,范例client和server使用了c++17的特性,我们需要升级编译器(比如, clang >= 8.0, 或 gcc >= 8.0).

四、QUIC面临的挑战

  1. 路由封杀UDP 443端口(这正是QUIC部署的端口)
  2. UDP包过多,由于QoS(Quality of Service,服务质量)限定,会被服务器商认 为是攻击,UDP包被丢弃
  3. 无论是路由器还是防火墙目前对QUIC都还没做好准备
  4. QUIC有较多的开源库,标准尚未真正落地,对应的开源库没有经过充分的验证, 不建议中小厂商在QUIC上完全跟进。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/357411.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu22.04笔记: 更换为阿里源

没有按照LTS 版本 会遇到下面问题: 参考:https://zhuanlan.zhihu.com/p/691625646 Ubuntu 22.04代号为:jammy Ubuntu 20.04代号为:focal Ubuntu 19.04代号为:disco Ubuntu 18.04代号为:bionic Ubuntu …

ReactNative和Android通信

初始化一个RN项目以后,接下来想要让Android与React Native通信 写一个继承自ReactContextBaseJavaModule类的子类,重写getName方法 package com.awesomeprojectimport android.util.Log import android.widget.Toast import com.facebook.react.bridge.…

Apache Doris 之 Docker 部署篇

前言 在现代数据驱动的商业环境中,实时数据分析和高并发查询能力是企业成功的关键因素之一。传统的数据仓库和分析工具在面对大规模数据处理和实时分析需求时,往往力不从心。Apache Doris 作为一个现代的 MPP 数据库管理系统,凭借其强大的查…

最新Sublime Text软件安装包分享(汉化版本)

Sublime Text 是一款广受欢迎的跨平台文本编辑器,专为代码、标记和散文编辑而设计。它以其简洁的用户界面、强大的功能和高性能而著称,深受开发者和写作者的喜爱。 一、下载地址 链接:https://pan.baidu.com/s/1kErSkvc7WnML7fljQZlcOg?pwdk…

监控 Prometheus源码安装实战和动态更新 Centos7

安装go环境 下载go安装包 #创建文件夹 mkdir /usr/local/software #进入文件夹 cd /usr/local/software #下载安装包 wget https://dl.google.com/go/go1.17.6.linux-amd64.tar.gz配置go环境变量 #解压 tar -zxvf go1.17.6.linux-amd64.tar.gz#配置环境变量 echo "exp…

【GD32】从零开始学兆易创新32位微处理器——RTC实时时钟+日历例程

1 简介 RTC实时时钟顾名思义作用和墙上挂的时钟差不多,都是用于记录时间和日历,同时也有闹钟的功能。从硬件实现上来说,其实它就是一个特殊的计时器,它内部有一个32位的寄存器用于计时。RTC在低功耗应用中可以说相当重要&#xf…

【调试笔记-20240619-Windows-Typescripts中类型不匹配的解决方法】

调试笔记-系列文章目录 调试笔记-20240619-Windows-Typescripts中类型不匹配的解决方法 文章目录 调试笔记-系列文章目录调试笔记-20240619-Windows-Typescripts中类型不匹配的解决方法 前言一、调试环境操作系统:Windows 10 专业版调试环境调试目标 二、调试步骤搜…

Linux 五种IO模型

注:还有一种信号驱动IO,使用较少暂不讨论; 一,区分阻塞、非阻塞和同步、异步 看了很多文章对这两组概念解释和对比,说的太复杂了,其实没必要,两句话就能说清楚。 首先,对于读数据rec…

Qt制作程序启动界面类QSplashScreen实例测试详解

目录 一、QSplashScreen的概述 二、QSplashScreen静态图片加载 1、主程序实现 2、mainwindow.h实现 3、mainwindows.cpp实现 三、QSplashScreen动态图片加载 1、主程序实现 2、mainwindow.h实现 3、mainwindows.cpp实现 一、QSplashScreen的概述 QSplashScreen&#x…

C++并发之协程实例(三)(co_await)

目录 1 协程2 实例3 运行 1 协程 协程(Coroutines)是一个可以挂起执行以便稍后恢复的函数。协程是无堆栈的:它们通过返回到调用方来暂停执行,并且恢复执行所需的数据与堆栈分开存储。这允许异步执行的顺序代码(例如,在没有显式回调…

指纹浏览器与虚拟机的区别及在跨境电商中的应用

在如今数字化世界中,隐私和安全变得愈发重要。许多人在网络上进行敏感操作,如网上购物、在线银行、社交媒体管理等。为了保护自己的隐私,人们常常会寻求一些额外的工具,比如指纹浏览器和虚拟机。这两种工具在保护个人隐私方面都有…

sqoop的安装配置

1. 上传并解压安装包 tar -zxvf sqoop-1.4.7.bin__hadoop-2.6.0.tar.gz -C ../server/ 重命名:mv sqoop-1.4.7.bin__hadoop-2.6.0 sqoop 2. 配置环境变量 sudo vim /etc/profile # 配置sqoop的环境变量 export SQOOP_HOME/export/server/sqoop export PATH$PATH…

Linux htop命令使用

文章目录 简介界面介绍第一行第二行第三行第四行 如何使用 简介 htop 是一个类似于 top 的命令,但具有更丰富的功能和更友好的界面。它可以实时显示系统中各个进程的资源占用情况,如 CPU 使用率、内存使用率等。以下是对 htop 命令的完全解析&#xff1…

嵌入式实验---实验五 串口数据接收实验

一、实验目的 1、掌握STM32F103串口数据接收程序设计流程; 2、熟悉STM32固件库的基本使用。 二、实验原理 1、STM32F103R6能通过查询中断方式接收数据,每接收到一个字节,立即向对方发送一个相同内容的字节,并把该字节的十六进…

Python: HexBinDecOct

因为: f0b1001110# 十进制 int()a0*2**01*2**11*2**21*2**30*2**40*2**51*2**6print(a)# 八进制 oct()print(78/8,78%8)# 110 001 001 8 116print(1*2**00*2**10*2**2,1*2**00*2**10*2**2,0*2**01*2**11*2**2)#十六进制 hex()#0 100 1110 16 4Eprint(sixteenFoo(0*…

如何在Qt Designer中管理QSplitter

问题描述 当按下按钮时,我希望弹出一个对话框,用户可以在其中选择内容并最终按下 ‘Ok’ 按钮。我想在这个对话框中放置一个 QSplitter,左侧面板将显示树状结构,右侧将显示其他内容。如何正确实现这一点? 从 Qt 的示…

oracle 主从库中,从库APPLIED为YES ,但是主库任然为NO

主库 从库 从库已经APPLIED但是主库为APPLIED, 主数据库和备用数据库之间的ARCH-RFS心跳Ping负责更新主数据库上v$archived_log的APPLICED列。 在主数据库上有一个指定的心跳ARCn进程来执行此Ping。如果此进程开始挂起,它将不再与远程RFS进程通信&#…

git拉取gitee项目到本地

git安装等不做赘述。 根据需要选择不同操作 1.只是单纯拉取个项目,没有后续的追踪等操作 不需要使用git init初始化本地文件夹 新建一个文件夹用于存储项目,右键选择 git bash here 会出现命令行窗口 如果像我一样,只是拉取个项目作业&…

Python爬虫技术:动态JavaScript加载音频的解析

在当今的互联网世界中,JavaScript已成为构建丰富交互体验不可或缺的技术。然而,对于网络爬虫开发者来说,JavaScript动态生成的内容却带来了不小的挑战。音频内容的动态加载尤其如此,因为它们往往涉及到复杂的用户交互和异步数据加…

xxe漏洞学习

一、什么是xxe漏洞 XXE就是XML外部实体注入,当允许引用外部实体时, XML数据在传输中有可能会被不法分子被修改,如果服务器执行被恶意插入的代码,就可以实现攻击的目的攻击者可以通过构造恶意内容,就可能导致任意文件读…