QUIC协议详解及NodeJs简单示例

如题所述

第1个回答  2024-09-04

QUIC协议是一个新的通讯协议,基于UDP的传输协议并希望最终取代所有基于TCP的HTTP请求。熟悉UDP的人都应该清楚为什么要使用QUIC。UDP是的特点是不可靠、数据包经常丢失、重新排序、重复等等。UDP不包括任何更高级别协议(如HTTP)严格要求的TCP的可靠性和顺序保证,这就是QUIC的用武之地。

本文简单介绍一下什么是QUIC,并NodeJs实现一个简单的示例,GitHub仓库。

QUIC协议简介

先回顾一下UDP,UDP(用户数据报协议)是ISO参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。UDP协议基本上是IP协议与上层协议的接口。

而QUIC协议是在UDP之上定义了一个层,该层将错误处理、可靠性、流控制和内置安全性(通过TLS1.3)引入UDP。实际上,它在UDP之上重新实现了大部分TCP的功能,但有一个关键区别:与TCP不同的是,它仍然可以不按顺序传输数据包。

QUIC通过在加密信封内重新实现基本传输服务来解决这个问题,使用UDP来跨越互联网。谷歌八年前首次宣布推出谷歌QUIC,在谷歌浏览器和谷歌服务之间使用它。这使他们能够独立于操作系统或操作系统更新计划进行改进。

GoogleQUIC为Chrome提供了许多性能优势,其他公司也开始为该协议做出贡献。

QUIC协议特点无队头阻塞

QUIC连接上的多个Stream之间并没有依赖,都是独立的,也不会有底层协议限制,某个流发生丢包了,只会影响该流,其他流不受影响。而什么是对头阻塞,可以参阅《TCP对头阻塞》

灵活性、安全性和减少延迟

QUIC引入了许多其他重要功能:

QUIC连接独立于网络拓扑运行:一旦建立了QUIC连接,源和目标IP地址和端口都可以更改,而无需重新建立连接。这在从一种类型的网络切换到另一种类型的移动设备(例如LTE到WiFi)上变得特别有用。

QUIC连接是安全和加密的:TLS1.3支持直接融入到协议中,所有QUIC流量都经过加密。

QUIC为UDP添加了关键的流量控制和错误处理,并包含重要的安全机制以防止一系列拒绝服务攻击。

QUIC添加了对零往返HTTP请求的支持:也就是说,与HTTPoverTLSoverTCP不同,它需要在客户端和服务器之间进行多次数据交换以建立TLS会话,然后才能传输任何HTTP请求数据,QUIC允许HTTP请求标头作为TLS握手的一部分发送。正在建立QUIC连接,显着减少新连接的初始延迟。

适用性和可管理性

加密传输协议对工程师选择传输协议和网络运营商监视活动都有影响。

QUIC传输协议的适用性描述了可能希望使用QUIC作为传输层的应用程序协议的注意事项。QUIC的特性在一些有趣和微妙的方面与TCP的特性不同,例如握手完成之前数据的可用性,或者多个同时流的可用性。

QUIC传输协议的可管理性描述了加密传输层对网络监控和管理的影响。许多网络假定能够检查TCP的状态以发现网络问题(性能差、丢包率高)或滥用流量(数据泄露、攻击)的迹象。

浏览器支持

六年前,谷歌将QUIC引入IETF以开始标准流程,IETF的贡献者表示有兴趣从他们的实验协议开始开发一种新的传输,就有了专有版本通常称为“GoogleQUIC”或“gQUIC”。

IETF在2016年成立了一个QUIC工作组,采用Google的特定于Web的实现并将其调整为通用传输协议。就这样慢慢就有了HTTP/3,它使用IETFQUIC作为传输。

所以在考虑浏览器支持的时候,就是以HTTP3的支持为标准:

QUIC协议实现

在实现新的QUIC支持的同时,需要使用一个新的顶级内置quic模块来公开API,不过需要自行编译,为避免对自身开发环境的影响,建议使用Docker,如有兴趣可以查看项目docker-nodejs里面有完整的代码及Docker运行方式。

quic模块公开了一个createSocket函数,此函数是可以创建可用作QUIC服务器或客户端的QuicSocket对象实例。

下面来创建服务端,如下:

const{createQuicSocket}=require("net");const{readFileSync}=require("fs");constport=process.env.NODE_PORT||3005;//定义HTTP默认端口或者从NODE_PORT环境变量获取constkey=readFileSync("./ssl_certs/server.key");constcert=readFileSync("./ssl_certs/server.crt");constca=readFileSync("./ssl_certs/server.csr");constservername="localhost";constalpn="hello";//创建QUICUDPIPv4套接字绑定到本地IP端口3005constserver=createQuicSocket({endpoint:{port}});//密钥和证书来保护新连接,使用虚拟的hello应用协议。server.listen({key,cert,alpn});server.on("session",(session)=>{session.on("stream",(stream)=>{stream.pipe(stream);});});server.on("listening",()=>{console.info(`listeningon${port}...`);console.info("inputcontent!");});

接下来创建客户端,这里在同一个文件中模拟客户端请求,如下:

constsocket=createQuicSocket({client:{key,cert,ca,requestCert:true,alpn,servername,},});constreq=socket.connect({address:servername,port,});req.on("secure",()=>{conststream=req.openStream();//stdin->streamprocess.stdin.pipe(stream);stream.on("data",(chunk)=>console.success("client(on-secure):",chunk.toString()));stream.on("end",()=>console.info("client(on-secure):end"));stream.on("close",()=>{console.warn("streamisclosed!");socket.close();});stream.on("error",(err)=>console.error(err));});

如果本地nodejs版本支持quic,那么可以直接启动:

npmrunstart

如果不支持,建议从Dokcer进行启动,如下:

dockerrun-it--rm--namequichello-p3005:3005-eNODE_ENV=development-v$PWD:/data/node/app--entrypoint'/bin/sh'node-quic-c'npminstall&&npmrunstart

运行效果如下:

作者:天行无忌

logo设计

创造品牌价值

¥500元起

APP开发

量身定制,源码交付

¥2000元起

商标注册

一个好品牌从商标开始

¥1480元起

公司注册

注册公司全程代办

¥0元起

    官方电话官方服务
      官方网站八戒财税知识产权八戒服务商企业需求数字市场
相似回答
大家正在搜