QUIC协议 对比 TCP/UDP 协议

Posted IT职场笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QUIC协议 对比 TCP/UDP 协议相关的知识,希望对你有一定的参考价值。

QUIC协议是HTTP3引入的,所以需要了解HTTP的版本迭代。

HTTP1.x

  1. 队头阻塞:下个请求必须在前一个请求返回后才能发出,导致带宽无法被充分利用,后续请求被阻塞(HTTP 1.1 尝试使用流水线(Pipelining)技术,但先天 FIFO(先进先出)机制导致当前请求的执行依赖于上一个请求执行的完成,容易引起队头阻塞,并没有从根本上解决问题)
  2. 协议开销大:header里携带的内容过大,且不能压缩,增加了传输的成本
  3. 传输不安全:采用文本形式传输,所有传输的内容都是明文,且客户端和服务器端都无法验证对方的身份,这在一定程度上无法保证数据的安全性
  4. 单向请求:只能单向请求,客户端请求什么,服务器返回什么
  5. HTTP 1.0 和 HTTP 1.1 的区别:
  • HTTP 1.0:仅支持保持短暂的TCP连接(连接无法复用);不支持断点续传;前一个请求响应到达之后下一个请求才能发送,存在队头阻塞
  • HTTP 1.1:默认支持长连接(请求可复用TCP连接);支持断点续传(通过在 Header 设置参数);优化了缓存控制策略;管道化,可以一次发送多个请求,但是响应仍是顺序返回,仍然无法解决队头阻塞的问题;新增错误状态码通知;请求消息和响应消息都支持Host头域
 

HTTP2

解决 HTTP1.x 的一些问题,但是解决不了底层 TCP 协议层面上的队头阻塞问题。

  1. 二进制传输:二进制格式传输数据解析起来比文本更高效
  2. 多路复用:重新定义底层 http 语义映射,允许同一个连接上使用请求和响应双向数据流。同一域名只需占用一个 TCP 连接,通过数据流(Stream)以帧为基本协议单位,避免了因频繁创建连接产生的延迟,减少了内存消耗,提升了使用性能,并行请求,且慢的请求或先发送的请求不会阻塞其他请求的返回
  3. Header压缩:减少请求中的冗余数据,降低开销
  4. 服务端可以主动推送:提前给客户端推送必要的资源,这样就可以相对减少一点延迟时间
  5. 流优先级:数据传输优先级可控,使网站可以实现更灵活和强大的页面控制
  6. 可重置:能在不中断 TCP 连接的情况下停止数据的发送

缺点:HTTP 2中,多个请求在一个TCP管道中的,出现了丢包时,HTTP 2的表现反倒不如HTTP 1.1了。因为 TCP 为了保证可靠传输,有个特别的“丢包重传”机制,丢失的包必须要等待重新传输确认,HTTP 2出现丢包时,整个 TCP 都要开始等待重传,那么就会阻塞该TCP连接中的所有请求。而对于 HTTP 1.1 来说,可以开启多个 TCP 连接,出现这种情况反到只会影响其中一个连接,剩余的 TCP 连接还可以正常传输数据

 

HTTP3

HTTP 是建立在 TCP 协议之上,所有 HTTP 协议的瓶颈及其优化技巧都是基于 TCP 协议本身的特性,HTTP2 虽然实现了多路复用,底层 TCP 协议层面上的问题并没有解决(HTTP 2.0 同一域名下只需要使用一个 TCP 连接。但是如果这个连接出现了丢包,会导致整个 TCP 都要开始等待重传,后面的所有数据都被阻塞了),而 HTTP3 的 QUIC 就是为解决 HTTP2 的 TCP 问题而生。

  

TCP和UDP回顾

1、TCP 是什么

TCP:全称为传输控制协议,是一种面向连接的、可靠的、基于字节流的传输层通信协议,由 IETF 的 RFC 793 定义。TCP 是面向连接的、可靠的流协议。

  1. 面向连接(存在三次握手)
  2. 只能进行点对点的数据传输
  3. 面向字节流(TCP 不像 UDP 一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输)
  4. 可靠传输(依靠 TCP 的段编号以及确认序号)
  5. 拥塞控制(网络出现拥塞的时候,TCP 能够减小向网络注入数据的速率和数量,缓解拥塞)
  6. 提供全双工通信(通信双方的应用程序在任何时候都能发送数据)
  7. 存在队头阻塞(使用序列号来标识数据的顺序,数据必须按照顺序处理)

 

 

2、UDP 是什么?

UDP:全称为用户数据报协议,与 TCP 协议一样用于处理数据包,是一种面向无连接不可靠的协议。关注把数据报文传输出去,不关心是否安全到达。

  1. 面向无连接(不需要三次握手)
  2. 支持一对多,多对多,多对一
  3. 不可靠(原因:通信都不需要建立连接、没有拥塞控制所以网络条件不好的情况下可能会导致丢包)
  4. 传输数据高效

 

 

QUIC 对比 TCP/UDP 的优缺点

QUIC 协议是 Google 提出的一套基于 UDP 的开源协议,它汇集了 TCP和 UDP 的优点,传输高效并且可靠。

1、QUIC 的优点

(1)迭代更新快

TCP 和 UDP 协议是操作系统内核实现的,部署进度慢。QUIC直接基于客户端实现,能实现快速迭代更新

(2)没有队头阻塞的多路复用

TCP 使用序列号来标识数据的顺序,数据必须按照顺序处理,可能会造成队头阻塞。HTTP2 支持多路复用,但是由于强制使用 TLS,还存在一个 TLS 协议层面的队头阻塞,QUIC 最基本的传输单元是 Packet,不会超过 MTU 的大小,整个加密和认证过程都是基于 Packet 的,不会跨越多个 Packet。这样就能避免 TLS 协议存在的队头阻塞。Stream 之间相互独立,比如 Stream2 丢了一个 Pakcet,不会影响 Stream3 和 Stream4,所以也不存在 TCP 队头阻塞。

(3)握手更迅速

TCP需三次握手才能建立连接,有等待时延,如果用了TLS加密,还会进一步增加时延。QUIC采用了类似于TCP Fast Open的设计,在之前已经连接过的情况下可以无需握手,直接开始传送数据,连接建立时延为0

 

(4)前向纠错

QUICTCP一个主要的核心区别就是:TCP采用 重传 机制,而QUIC采用 纠错 机制。如果发生丢包的话,TCP首先需要一个等待延时来判断发生了丢包,然后再启动重传机制,在此期间会对连接造成一定的阻塞(并且TCP窗口是缓慢增大的,Web这种突发性快速连接情况下窗口会相对较小),从而影响传输时间。而QUIC采用了一种脑洞极大的前向纠错(FEC)方案,类似于RAID5,将N个包的校验和(异或)建立一个单独的数据包发送,这样如果在这N个包中丢了一个包可以直接恢复出来,完全不需要重传,有利于保证高速性,N可以根据网络状况动态调整

 

(5)连接保持

TCP 连接是由四元组标识的(源 IP,源端口,目的 IP,目的端口),当其中一项发生改变,都需要重新建立和服务端的 TCP 连接。QUIC 连接不再以 IP 及端口四元组标识,而是以一个 64 位的随机数作为 ID 来标识,这样就算 IP 或者端口发生变化时,只要 ID 不变,这条连接依然维持着。这就意味着:在IP地址和端口变化的情况下(比如从Wi-Fi切换到流量),可以无需重新建立连接,继续通信

(6)加密技术比TLS性能好,同时具有各种攻击防御策略。

(7)能实现证书压缩,减少证书传输量,针对包头进行验证等。

 

2、QUIC 的不足

(1)QUIC 基于 UDP ,目前很多网络运营商会降低 UDP 包的优先级,使得 UDP 丢包率特别高

(2)支持的浏览器少

计算机网络传输层(TCP/UDP)

TCP和UDP 对比

  • TCP(Transmission Control Protocol),传输控制协议
  • UDP(User Datagram Protocol),用户数据报协议

UDP协议

  • UDP是无连接的,减少了建立和释放连接的开销
  • UDP尽最大能力交付,不保证可靠交付
  • 不需要维护一些复杂的参数,首部只有8个字节(TCP的首部至少20个字节)
  • UDP长度(Length) ,占16位,首部的长度 + 数据的长度

  • 检验和:计算内容:伪首部 + 首部 + 数据
  • 伪首部:仅在计算检验和时起作用,并不会传递给网络层

端口补充

  • UDP首部中端口是占用2字节,可以推测出端口号的取值范围是:0~65535
  • 客户端的源端口是临时开启的随机端口
  • 防火墙可以设置开启\\关闭某些端口来提高安全性
  • 常用命令行
    netstat –an:查看被占用的端口
    netstat –anb:查看被占用的端口、占用端口的应用程序
    telnet 主机 端口:查看是否可以访问主机的某个端口

TCP协议

数据格式

数据格式

  • 数据偏移 ,占4位,取值范围是0x0101-0x1111,乘以4得首部长度(20~60字节)(Header Length)。
  • 保留,占6位,目前全为0。
  • TCP的数据长度 = 网络层的总长度 – 网络层的首部长度 – 传输层的首部长度
  • 检验和跟UDP一样,TCP检验和的计算内容:伪首部 + 首部 + 数据
  • 伪首部:占用12字节,仅在计算检验和时起作用,并不会传递给网络层
  • 标识位
    URG(Urgent) ,当URG=1时,紧急指针字段才有效。表明当前报文段中有紧急数据,应优先尽快传送
    ACK(Acknowledgment),当ACK=1时,确认号字段才有效
    PSH(Push)
    RST(Reset) ,当RST=1时,表明连接中出现严重差错,必须释放连接,然后再重新建立连接
    SYN(Synchronization) ,当SYN=1、ACK=0时,表明这是一个建立连接的请求 ,若对方同意建立连接,则回复SYN=1、ACK=1
    FIN(Finish) ,当FIN=1时,表明数据已经发送完毕,要求释放连接
  • 序号(Sequence Number),占4字节
    首先,在传输过程的每一个字节都会有一个编号
    在建立连接后,序号代表:这一次传给对方的TCP数据部分的第一个字节的编号
  • 确认号(Acknowledgment Number)占4字节
    在建立连接后,确认号代表:期望对方下一次传过来的TCP数据部分的第一个字节的编号
  • 窗口(Window)占2字节
    这个字段有流量控制功能,用以告知对方下一次允许发送的数据大小(字节为单位)

TCP可靠传输

  • 如果接收窗口最多能接收4个包 ,但发送方只发了2个包
  • 接收方如何确定后面还有没有2个包? ,等待一定时间后没有第3个

SACK协议(选择性确认)

  • 在TCP通信过程中,如果发送序列中间某个数据包丢失(比如1、2、3、4、5中的3丢失了)
  • TCP会通过重传最后确认的分组后续的分组(最后确认的是2,会重传3、4、5)
  • 这样原先已经正确传输的分组也可能重复发送(比如4、5),降低了TCP性能
  • 为改善上述情况,发展出了SACK(Selective acknowledgment,选择性确认)技术
    告诉发送方哪些数据丢失,哪些数据已经提前收到
    使TCP只重新发送丢失的包(比如3),不用发送后续所有的分组(比如4、5)

问题

为什么选择在传输层就将数据“大卸八块”分成多个段,而不是等到网络层再分片传递给数据链路层?
因为可以提高重传的性能
需要明确的是:可靠传输是在传输层进行控制的
如果在传输层不分段,一旦出现数据丢失,整个传输层的数据都得重传
 如果在传输层分了段,一旦出现数据丢失,只需要重传丢失的那些段即可

TCP流量控制

接收方缓存区满了,发送方还在疯狂着发送数据 ,只能把数据包丢掉,大量的丢包会极大着浪费网络资源 ,所以要进行流量控制

  • 什么是流量控制?
    让发送方的发送速率不要太快,让接收方来得及接收处理
  • 原理
    通过窗口字段控制发送速率
    发送方窗口大小不能超过接收方给出窗口大小
    收到窗口的大小为0时停止发送数据

TCP拥塞控制

  • 拥塞控制 ,防止过多的数据注入到网络中 ,避免网络中的路由器或链路过载
  • 拥塞控制是一个全局性的过程 ,涉及到所有的主机、路由器 ,以及与降低网络传输性能有关的所有因素 ,是大家共同努力的结果
  • 相比而言,流量控制是点对点通信的控制

拥塞控制方法

  • 慢开始(slow start,慢启动)
    cwnd的初始值比较小,然后随着数据包被接收方确认(收到一个ACK)
    cwnd就成倍增长(指数级)

  • 拥塞避免(congestion avoidance)
    ssthresh(slow start threshold):慢开始阈值,cwnd达到阈值后,以线性方式增加
     拥塞避免(加法增大):拥塞窗口缓慢增大,以防止网络过早出现拥塞
     乘法减小:只要网络出现拥塞,把ssthresh减为拥塞峰值的一半,同时执行慢开始算法(cwnd又恢复到初始值) 当网络出现频繁拥塞时,ssthresh值就下降的很快

  • 快速重传(fast retransmit)
     接收方
    1.每收到一个失序的分组后就立即发出重复确认
    2.使发送方及时知道有分组没有到达
    3.而不要等待自己发送数据时才进行确认
     发送方
    1.只要连续收到三个重复确认(总共4个相同的确认),就应当立即重传对方尚未收到的报文段
    2.而不必继续等待重传计时器到期后再重传

  • 快速恢复(fast recovery)
    当发送方连续收到三个重复确认,说明网络出现拥塞 ,就执行“乘法减小”算法,把ssthresh减为拥塞峰值的一半
     与慢开始不同之处是现在不执行慢开始算法,即cwnd现在不恢复到初始值 ,而是把cwnd值设置为新的ssthresh值(减小后的值) ,然后开始执行拥塞避免算法(“加法增大”),使拥塞窗口缓慢地线性增大

名词解析

  • MSS(Maximum Segment Size):每个段最大的数据部分大小 ✓在建立连接时确定
  • cwnd(congestion window):拥塞窗口 rwnd(receive window):接收窗
  • swnd(send window):发送窗口 ✓swnd = min(cwnd, rwnd)

拥塞控制方法 —— 快重传+快恢复

TCP三次握手

  • CLOSED:client处于关闭状态
  • LISTEN:server处于监听状态,等待client连接
  • SYN-RCVD:表示server接受到了SYN报文,当收到client的ACK报文后,它会进入到ESTABLISHED状态
  • SYN-SENT:表示client已发送SYN报文,等待server的第2次握手
  • ESTABLISHED:表示连接已经建立

三次握手的主要目的是为了服务端和客户端双方交换信息。三次握手过程中并不会发送数据部分,只是头部信息交换。

问题

为什么建立连接的时候,要进行3次握手?2次不行么?
主要目的:防止server端一直等待,浪费资源

  • 如果建立连接只需要2次握手,可能会出现的情况
    假设client发出的第一个连接请求报文段,因为网络延迟,在连接释放以后的某个时间才到达server
    本来这是一个早已失效的连接请求,但server收到此失效的请求后,误认为是client再次发出的一个新的连接请求
    于是server就向client发出确认报文段,同意建立连接
    如果不采用“3次握手”,那么只要server发出确认,新的连接就建立了
    由于现在client并没有真正想连接服务器的意愿,因此不会理睬server的确认,也不会向server发送数据
    但server却以为新的连接已经建立,并一直等待client发来数据,这样,server的很多资源就白白浪费掉了
  • 采用“三次握手”的办法可以防止上述现象发生
    例如上述情况,client没有向server的确认发出确认,server由于收不到确认,就知道client并没有要求建立连接

第3次握手失败了,会怎么处理?
此时server的状态为SYN-RCVD,若等不到clientACK,server会重新发送SYN+ACK
如果server多次重发SYN+ACK都等不到client的ACK,就会发送RST包,强制关闭连接

TCP四次挥手

  • FIN-WAIT-1:表示想主动关闭连接 ,向对方发送了FIN报文,此时进入到FIN-WAIT-1状态
  • CLOSE-WAIT:表示在等待关闭
    当对方发送FIN给自己,自己会回应一个ACK报文给对方,此时则进入到CLOSE-WAIT状态
    在此状态下,需要考虑自己是否还有数据要发送给对方,如果没有,发送FIN报文给对方
  • FIN-WAIT-2:只要对方发送ACK确认后,主动方就会处于FIN-WAIT-2状态,然后等待对方发送FIN报文
  • CLOSING:一种比较罕见的例外状态
    表示你发送FIN报文后,并没有收到对方的ACK报文,反而却也收到了对方的FIN报文
    如果双方几乎在同时准备关闭连接的话,那么就出现了双方同时发送FIN报文的情况,也即会出现CLOSING状态
    表示双方都正在关闭连接
  • LAST-ACK:被动关闭一方在发送FIN报文后,最后等待对方的ACK报文 ,当收到ACK报文后,即可进入CLOSED状态了
  • TIME-WAIT:表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可进入CLOSED状态了 如果FIN-WAIT-1状态下,收到了对方同时带FIN标志和ACK标志的报文时
    ✓ 可以直接进入到TIME-WAIT状态,而无须经过FIN-WAIT-2状态
  • CLOSED:关闭状态
  • 由于有些状态的时间比较短暂,所以很难用netstat命令看到,比如SYN-RCVD、FIN-WAIT-1等

TCP释放链接细节

  • TCP/IP协议栈在设计上,允许任何一方先发起断开请求。这里演示的是client主动要求断开
  • client发送ACK后,需要有个TIME-WAIT阶段,等待一段时间后,再真正关闭连接
    一般是等待2倍的MSL(Maximum Segment Lifetime,最大分段生存期)
    ✓ MSL是TCP报文在Internet上的最长生存时间 ✓每个具体的TCP实现都必须选择一个确定的MSL值,RFC 1122建议是2分钟
    ✓ 可以防止本次连接中产生的数据包误传到下一次连接中(因为本次连接中的数据包都会在2MSL时间内消失了)
  • 如果client发送ACK后马上释放了,然后又因为网络原因,server没有收到client的ACK,server就会重发FIN
    这时可能出现的情况是
    1 client没有任何响应,服务器那边会干等,甚至多次重发FIN,浪费资源
    2 client有个新的应用程序刚好分配了同一个端口号,新的应用程序收到FIN后马上开始执行断开连接的操作,本来 它可能是想跟server建立连接的

问题

为什么释放连接的时候,要进行4次挥手?
TCP是全双工模式
第1次挥手:当主机1发出FIN报文段时
✓ 表示主机1告诉主机2,主机1已经没有数据要发送了,但是,此时主机1还是可以接受来自主机2的数据
第2次挥手:当主机2返回ACK报文段时
✓ 表示主机2已经知道主机1没有数据发送了,但是主机2还是可以发送数据到主机1的
第3次挥手:当主机2也发送了FIN报文段时
✓ 表示主机2告诉主机1,主机2已经没有数据要发送了
第4次挥手:当主机1返回ACK报文段时
✓ 表示主机1已经知道主机2没有数据发送了。随后正式断开整个TCP连接

以上是关于QUIC协议 对比 TCP/UDP 协议的主要内容,如果未能解决你的问题,请参考以下文章

TCP协议

计算机网络传输层(TCP/UDP)

计算机网络传输层(TCP/UDP)

计算机网络传输层(TCP/UDP)

传输层-第三节:TCP和UDP对比

计算机网络传输层(TCP/UDP)