看到google 提交了http3 over QUIC 的标准化草案, 才发现2012年我在 UDP可靠传输那些事 https://blog.csdn.net/danscort2000/article/details/8432778 一文中给出的那些痛点,居然给出了解决方法, 最大的局限就是我当时说的, sendto 和recvfrom 函数, 2014年Linux核心添加了 recvmmsg 和 sendmmsg 函数,这样就和tcp send/recv函数一样,一次调用就可以读写多个数据包,解决了用户态和内核态之间频繁切换的问题, (但是, windows 目前还没有支持这两个函数)这样,如果只是单纯的做发包测试或者收报测试,运行在应用层[测试的时候优先级为默认]默认16包下,吞吐提升我估计大概会达到 16 *2 /3 也就是原先的10倍多一点,如果整合到具体的可靠传输协议中进行测试[包含包头的校验等一切算法], 按照当时的经验, 性能提升[也是按16包默认缓冲]估计会在35%左右,而google 的 QUICK 正是基于这两个recvmmsg sendmmsg 实现了高效率的UDP可靠传输.

QUIC简化了握手过程,包括TLS的握手过程,这样在处理海量的短连接的时候,性能优势是非常明显的 [请注意,是海量+短连接,要同时满足这两个条件] , 下面是QUIC旧版本的实现部分包头内容分解,说句老实话, 象QUIC这种UDP可靠传输,还是应该使用纯C来写更简洁明了(虽然我大部分时间也是用c++,但是这种协议层的实现确实应该使用纯C, c++ try catch不到位的话,很容易引发崩溃等各种漏洞或者攻击),这种c++写法我个人无法接受,当然google为了照顾go语言等面向对象的需要,可能就优先考虑c++了,但是真的看着挺乱的, 但是这里可能有问题,使用特制版的Linux使用RAW模式,应该比较容易发起性能攻击,这可能比TCP的DDOS更严重,因为UDP模式下,要伪造包太容易了, 攻击发起方需要的电脑数量比TCP少几何级,只是一种猜测,我没做测试,但是由于这种短握手机制,性能攻击虽然不是漏洞,但至少是缺陷,而且防火墙都不好处理.

QUIC_EXPORT_PRIVATE size_t
GetPacketHeaderSize(QuicVersion version,
                    QuicConnectionIdLength connection_id_length,
                    bool include_version,
                    bool include_diversification_nonce,
                    QuicPacketNumberLength packet_number_length);

// Index of the first byte in a QUIC packet of encrypted data.
QUIC_EXPORT_PRIVATE size_t
GetStartOfEncryptedData(QuicVersion version, const QuicPacketHeader& header);

QUIC_EXPORT_PRIVATE size_t
GetStartOfEncryptedData(QuicVersion version,
                        QuicConnectionIdLength connection_id_length,
                        bool include_version,
                        bool include_diversification_nonce,
                        QuicPacketNumberLength packet_number_length);

struct QUIC_EXPORT_PRIVATE QuicPacketPublicHeader {
  QuicPacketPublicHeader();
  QuicPacketPublicHeader(const QuicPacketPublicHeader& other);
  ~QuicPacketPublicHeader();

// Universal header. All QuicPacket headers will have a connection_id and
  // public flags.
  QuicConnectionId connection_id;
  QuicConnectionIdLength connection_id_length;
  bool reset_flag;
  bool version_flag;
  QuicPacketNumberLength packet_number_length;
  QuicVersionVector versions;
  // nonce contains an optional, 32-byte nonce value. If not included in the
  // packet, |nonce| will be empty.
  DiversificationNonce* nonce;
};

// Header for Data packets.
struct QUIC_EXPORT_PRIVATE QuicPacketHeader {
  QuicPacketHeader();
  explicit QuicPacketHeader(const QuicPacketPublicHeader& header);
  QuicPacketHeader(const QuicPacketHeader& other);

QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
      std::ostream& os,
      const QuicPacketHeader& s);

QuicPacketPublicHeader public_header;
  QuicPacketNumber packet_number;
};

至于QUIC 包头的实现,几乎是我当年编写的UDP可靠传输的翻版, QUIC使用了64位随机数ID作为连接,[我的代码是采用了32位无符号下标加 服务器端和客户端各32位随机数组成的加密[一共是128位,但是每包传输只需要用到96位],并在握手的时候又添加了一个可选的2个64位无符号加密数字,加服务器端一共是256位加密数字, 不知道QUIC只使用64位随机数做ID是否能适应未来],

QUIC彻底去掉了基于IP/PORT模式的认证[只基于64位ID随机数],这样就解决了移动端在切换基站导致ip/port发生变化时,可以无缝平滑的切换,而无须重新连接, 因此在移动端平台会有优于TCP的体验,这一点没有任何疑问,因为我当年测试中就已经有这个结果了,当然安全性嘛,这可能还需要经过长时间的验证,网络支付强烈建议不要使用QUIC,任何涉及到金钱或者强加密的内容我建议尽量不要使用QUIC.

QUIC采用了严格的递进packet number来标记发送包的序列号, 和TCP不同, tcp遇到丢包的时候需要重新投递相同标号的包, 这样在tcp收到包的时候,其实是无法区分究竟是原来的包还是重发的包,因此导致了重传时间计算的混淆,而QUIC采用了递进包编号,而包的内容是根据偏移来确定的,也就是offset, 因此如果两个包offset一样,而packet number不同,那么只需要计算packet number 之间的数字就能知道是否重传的包,并统计次数. 这里有个问题哈,个人觉得日后可能会引发安全问题,暂时跳过,但是根据我的经历,这种设计完全是画蛇添足,packet number 应该取消的,而是根据类型使用一个bit直接标记为是原始包还是重发包就足够了,因为如果发生了超过+3packet number, 通常都是网络切换导致的,如果按常规的拥堵算法,会直接导致一个卡顿,而且我们一般的延迟算法,对超过3次延迟普遍都归类到3次,实际并不会增加N倍延迟,而是有个上限的, 这个packet number 我觉得根本就是败笔,耗费了CPU计算资源,占用包头位置,空耗流量,没意义,一个bit足够了.

QUIC采用了stream 来当作整体块内容进行传输 , 这在实现单路连接模拟多路连接应用操作时,比TCP有效,由于tcp使用流模式,前面任何一个块里的片段丢失,会导致整个连接传输受阻,而QUIC 则没有这个问题,因为各个stream是独立的块,任何一块传输完成都可以可以被接收并执行处理.

QUIC 使用了和tcp滑动窗口控制拥塞不同的方法,而且严格禁止丢弃已经接收到的包,只要一个包被ack,那么就肯定被接收了,你不能因为缓冲满了就丢掉包让发送方重发.

QUIC的拥堵算法和TCP基本一样,不过做成了可选项,由于QUIC不是跑在内核层,如果有必要,可以针对无线网络高丢包环境,在QUIC层调整算法来实现更快的重发机制,这在TCP里是无法想像的.

QUIC已经自带加密,并支持TLS.

QUIC优点很多,UDP可靠传输的每个连接资源开销要远小于TCP,特别是处理海量连接的时候,更是明显,但是缺点也很明显,它没有跑在内核层,光靠recvmmsg sendmmsg优化[windows环境还没有这个优化],频繁的切换还是不可避免,而且目前也没有硬件针对QUIC进行优化,因此在处理大流量数据,或者需要更低的CPU开销的话,TCP可能更合适.

QUIC几乎是总结了之前所有UDP可靠传输实现的优缺点后重新造的一个轮子,不过凭借google这棵大树,加上在Linux内核开发的话语权,肯定会得到大范围的推广应用,但是,有很多缺点目前并没有暴露出来,包括安全方面. QUIC并不适合传输明文数据,明文传输使用QUIC是不够安全,必须结合TLS进行加密传输才能基本克服去掉IP/PORT引发的安全问题,目前也不能说用了TLS就绝对安全,因为大家都知道, TLS握手,真正的保密随机数可以说只有一个,现在没问题,不等于将来没问题.

如果你只是使用QUIC代替TCP做在线视频播放,我觉得目前是可行的,无线网络和移动端的实现只需要调整一下拥堵算法就能实现比TCP优秀的多感受[但是问题是,移动端运营商流量计费,如果遇到高丢包环境加错误的拥堵算法,可能会非常悲剧],至于其他方面,如果是网络游戏,那么不妨用QUIC代替其中的TCP,但是要用QUIC完全充当协议,肯定不行,它不是针对实时游戏开发的; 可以非常明显的看出,QUIC是特别针对无线网络的高丢包,ip地址动态切换的环境优化开发的,比较适合手机等无线移动平台的平滑使用,而且ip变化引发的流量损失会非常小,不需要全部重新加载,但是,为了弥补放弃ip/port带来的风险,对数据包采用了强加密强校验,而且这些加密校验都是需要CPU来完成的,没有硬件优化,因此不可避免的会导致移动平台CPU功耗相对TCP会大大增加,续航时间缩短等问题,如何取舍需要根据项目来决定的.

其实, UDP传输的最大优点除了可以实现类似TCP的可靠传输外,还可以支持时效性可靠传输等各种扩展,例如,在游戏开发中,有这样一种数据,希望能在一个短的时间,比如10秒内实现传输,如果没有传输成功,那么就丢弃它,还不能重复,这种实现我在自己的代码里管它叫时效性可靠传输,当然用在web上是没有用的,但是在很多场合,这种传输非常有效;  其次是多点互联,因为ipv6的崛起,完全带给我们不一样的网络环境,和IPV4环境下的多点互联不同[一把泪啊,各种的NAT,各种的穿透失败,除了内网,基本没法用], 在IPV6网络下,多点互联完全没有问题,这将给网络游戏的实现带来完全不同的场景,想像一下,比如网络游戏,本来只能支持30人每房间,现在我们通过互联P2P传输, 将原来服务器要承担的发送30个数据报,变成比如a/B各一个包,然后由A/B各自负责环状传播,这可以大大的节省服务器资源和带宽开销,一个房间支持更多的用户,带来更好的用户体验,但是QUIC并没有实现这个功能,还有其他很多扩展QUIC都没有实现,也许也是它的优点吧,专一实现可靠传输.

QUIC目前并没有普及,覆盖率还非常低,但是确实是一种趋势,但是UDP可靠传输并非万能,能清晰的知道它的优点和缺点,以及它可能的隐患是关键所在.

QUIC 协议的简单分析相关推荐

  1. 关于手游网络协议的简单分析

    前言 大多数加密方案都假定可信的发送者和接收者会通过一个不可信的通道通信. 虽然假设发送者会故意尝试愚弄接收者有点荒谬,但这确实是摆在开发者面前的问题.有些玩家是不可信的, 更糟的是, 他们能够通过客 ...

  2. android xmpp 语音,Android:Xmpp协议的简单分析

    概要 在IETF中,把IM协议分为四种协议: 1.IMPP(Instant Messaging And Presence Protocol) 2.PRIM(Presence And Instant M ...

  3. 科普:QUIC协议原理分析

    作者介绍:lancelot,腾讯资深研发工程师.目前主要负责腾讯 stgw(腾讯安全云网关)的相关工作,整体推进腾讯内部及腾讯公有云,混合云的七层负载均衡及全站 HTTPS 接入.对 HTTPS,SP ...

  4. RTSP协议的一些分析(三)——简单的rtsp服务器的实现

    目录 一.简介 二.套接字的创建 三.解析请求 四.OPTIONS的响应 五.DESCRIBE的响应 六.SETUP的响应 七.PLAY的响应 八.源码 一.简介 RTSP服务器有两个部分组成,一个是 ...

  5. QUIC协议原理分析

    C/C++Linux服务器开发/后台架构师知识体系 本文主要介绍 QUIC 协议产生的背景和核心特性. QUIC 概述 Quic 全称 quick udp internet connection [1 ...

  6. QUIC协议----简单学习整理

    引言 2022年6月,HTTP/3正式被标准化为RFC 9114,其将是HTTP超文本传输协议的第三个主要版本.HTTP协议作为一个简单的请求-响应协议,各个主要版本主要是在于优化传输效率及安全性方面 ...

  7. QUIC协议的分析,性能测试以及在QQ会员实践

    WeTest 导读 你听过HTTPS.HTTP2.0.SPDY,但是这些应用层协议都是基于可靠的传输层协议TCP来实现的.那么,基于高效的UDP协议有没有一种相对可靠的应用层协议呢? Why QUIC ...

  8. E百科 | 第2期 扒一扒能加速互联网的QUIC协议

    简介: 众所周知,QUIC(Quick UDP Internet Connection)是谷歌制定的一种互联网传输层协议,它基于UDP传输层协议,同时兼具TCP.TLS.HTTP/2等协议的可靠性与安 ...

  9. 扒一扒能加速互联网的QUIC协议

    简介:众所周知,QUIC(Quick UDP Internet Connection)是谷歌制定的一种互联网传输层协议,它基于UDP传输层协议,同时兼具TCP.TLS.HTTP/2等协议的可靠性与安全 ...

最新文章

  1. PCL:点云中的超体素数据
  2. SpringMVC注解@RequestParam全面解析
  3. 攻防世界Reverse第九题no-strings-attached
  4. 软件测试遇到的异常情况,豪之诺软件测试项目开发中遇到比较多的Bug总结
  5. Eclipse添加SVN插件:导入项目+上传项目+更新项目
  6. GC之Minor/Young/Major GC的区别
  7. 【Todo】Java类型转换总结
  8. css静态网页设计 北京旅游(1页) 北京旅游网页设计制作 简单静态HTML网页作品 我的旅游网页作业成品 学生旅游网站模板
  9. OUTLOOK 下邮件如何以人,文件夹来分类inbox
  10. Android那些你可能没了解过的---碎片化
  11. [cesium] | 城市警情模拟
  12. VTK读取序列DCM格式医学图像
  13. Python使用pillow库往图片上写入文字或覆盖另一张图片
  14. win安装夜神安卓模拟器
  15. hdu 1849 Rabbit and Grass Nim博弈
  16. Redis介绍及其简单使用方法
  17. 计算机配件模拟,电脑装机模拟各配件跑分及计算公式分享
  18. nefuoj1487时空乱流
  19. Bluetooth DUN 蓝牙拨号网络 (http://blog.sina.com.cn/s/blog_59b22a2e0100ildk.html)
  20. Python生成 gif 动图

热门文章

  1. linux下设置db2远程连接
  2. 日本最大的120家医用物资供应商列表
  3. 2022年全球市场碳化硅滑动轴承总体规模、主要生产商、主要地区、产品和应用细分研究报告
  4. linux挂载磁盘(自动挂载\解决重启后挂载磁盘消失的问题)
  5. 分布式事务之TX-LCN
  6. SIGCHLD信号(重点)
  7. 软件工程实训有必要吗_软件工程实训心得体会
  8. c语言规定 程序中各函数之间().,C语言基础笔试题
  9. 【许晓笛】EOS 什么是智能合约(3)
  10. 【思想】《人生效率手册》