使用UDP实现TCP的功能,会带来什么好处?

发布于:2024-04-17 ⋅ 阅读:(21) ⋅ 点赞:(0)

比较孤陋寡闻,只知道QUIC

TCP QUIC
握手延迟 TCP需要三次握手+TLS握手 三次握手+TLS握手放在一起,实现0RTT
头阻塞问题 TCP丢失保文,会影响所有的应用数据包 基于UDP封装传输层Stream,Stream内部保序,Stream之间不存在相互影响
传输控制 Seq二义性(重传)、SACK限制、RTT计算不准 吸取了TCP的问题,重新设计
连接迁移 五元祖实现连接标识 以一个 64 位的随机数作为 ID 来标识
实现层级 在传输层上实现 在应用层上实现

QUIC 流程简述

握手过程

《QUIC协议详解》- 1-RTT的连接过程

连接机制

一条 TCP 连接是由五元组标识的,分别是源 IP、源端口、目的 IP、目的端口、协议号

而QUIC 自己的逻辑里面维护连接的机制,不再以五元组标识,而是以一个 64 位的随机数作为 ID 来标识,而且 UDP 是无连接的,所以当 IP 或者端口变化的时候,只要 ID 不变,就不需要重新建立连接

重传机制

TCP 为了保证可靠性,通过使用序号和应答机制,来解决顺序问题和丢包问题

在 TCP 里面存在超时的采样存在不准确的问题

  • 发送一个包,发现没有返回,于是再发送,过一阵返回一个 ACK
  • ACK的返回,让客户端知道这个包收到了。但是这个往返时间是在ACK的时间减去第一个包时间,还是减去第二个包时间?

QUIC 也有个序列号,是递增的。任何一个序列号的包只发送一次,下次就要加一了。但为了保证包内容的一致性,会存在一个offset的概念,offset是唯一的,如果某个offset对应的包没有就重发,通过这个offset拼接成一个完整的数据流

多路复用机制

HTTP 2.0 的多路复用问题

  • HTTP/1.1可以使用多个TCP连接,但对连接数依然有限制,一次请求要等到连接中其他请求完成后才能开始(Pipeline机制也没能解决好这个问题),所以没有空闲连接的时候请求被阻塞,这是应用层的阻塞
  • HTTP/2底层使用了一个TCP连接,上层虚拟了stream,HTTP请求跟stream打交道,无需等待前面的请求完成,这确实解决了应用层的队首阻塞问题
  • 传输层的队首阻塞,TCP的应答是严格有序的,如果前面的包没到,即使后面的到了也不能应答,这样可能会导致后面的包被重传,窗口被“阻塞”在队首,这就是传输层的队首阻塞。 不管是HTTP/1.1还是HTTP/2

QUIC 连接上可以创建多个 stream,来发送多个 HTTP 请求。但是,QUIC 是基于 UDP 的,一个连接上的多个 stream 之间没有依赖

流量控制

QUIC 的流量控制也是通过 window_update,来告诉对端它可以接受的字节数

QUIC 的 ACK 是基于 offset 的,每个 offset 的包来了,进了缓存,就可以应答,应答后就不会重发,中间的空档会等待到来或者重发即可,而窗口的起始位置为当前收到的最大 offset,从这个 offset 到当前的 stream 所能容纳的最大缓存

参考资料