571
社区成员
发帖
与我相关
我的任务
分享1.1 基本原理
QUIC(Quick UDP Internet Connection)是谷歌制定的一种基于UDP的低时延的互联网传输层协议。
现今传输层协议有TCP 和 UDP两种。TCP即传输控制协议,提供面向连接的运输服务。提供一种可靠的面向连接的字节流传输层服务。UDP即用户数据报协议,是一种无连接的,提供不可靠交付的运输层协议。其与TCP 协议相比,UDP更轻量级,效率高,但可靠性不如TCP协议。因此,为弥补上述两个协议的缺陷,产生了基于 UDP 协议但却可靠的QUIC传输协议,因为它将很多可靠性的验证策略从系统层转移到应用层来做,这样可以使用更适合现代流媒体传输的拥塞控制策略。
QUIC在协议栈中的位置

QUIC数据包格式

QUIC原理我主要参考学习https://zhuanlan.zhihu.com/p/405387352这篇文章
建立链接:TLS 握手,用 1 个RTT 时间把通信密钥协商好,客户端缓存了 ServerConfig,下次建连直接使用缓存数据计算通信密钥,所以之后客户端不需要经过握手就可以发送应用数据。
可靠传输:发送端通过包号(PKN)和确认应答(SACK)来确认发送的包是否被接收端收到。QUIC 的数据包号是单调递增的,用于解决TCP重传歧义问题。接收端根据 offset 字段可以对异步到达的数据包进行排序。
流量控制:类似TCP,QUIC使用滑动窗口实现流量控制。
拥塞控制:QUIC通过慢启动、拥塞避免、拥塞发生、快速恢复这四个拥塞控制算法实现拥塞控制。
多路复用:一个请求就对应一条流,QUIC通过 Stream ID 就可以判断该数据帧属于哪个请求,通过给每个请求流都分配一个独立的滑动窗口,解决了TCP 层的队头阻塞问题。
1.2 优点
连接延迟低:客户端第一次连接服务器时,QUIC只需要1个RTT的延迟就可以建立可靠安全的连接,快于需要3个RTT的TCP。而且其在再次与服务器建立连接时可以实现0个RTT的连接建立延迟。
避免了线头阻塞问题:给每个请求流都分配一个独立的滑动窗口,解决了TCP 层的队头阻塞问题。
更安全可靠:QUIC用 Packet Number 代替 TCP 的 Sequence Number,可靠性得到提高,且所有报文头部都是经过认证和加密的。实现了前向安全,即用来产生会话密钥的长期密钥泄露出去,不会泄漏以前的通讯内容。
更好的拥塞控制:QUIC支持各种各样的拥塞控制算法,在应用程序层面就能实现不同的拥塞控制算法,灵活程度非常高。
网络切换性能好:QUIC包含一个连接标识符,该标识符唯一地标识客户端与服务器之间的连接,只要源IP地址发送一个包含此ID的数据包即可重新创建连接。
2.1 构建
这里我采用Microsoft's MsQuic,在Ubuntu 20.04上进行实验
安装git

从https://bbs.csdn.net/forums/msquic.git处下载源代码(经常下载失败,多试几次才下好)


安装powershell

安装Ubuntu20.04版本的.NET Core

安装SDK

安装cmake(这里我原先下的是3.16版本的cmake,在后面的构建步骤中一直报错,后来参考网上教程下载3.22版本的cmake才解决问题)

启动powershell

检查依赖并安装

构建(编译)

测试(对msquic提供的测试用例进行测试,以验证编译是否正确,需要较长的时间)

测试完成

2.2 样例测试
对MsQuic的参考样例进行测试
启动powershell

生成证书密钥


运行服务端

运行客户端

服务端运行结果

客户端运行结果


对参考样例源代码的分析如下:
服务端

客户端


作者:NP479+xc