TCP 与 UDP 的区别
TCP | UDP | |
---|---|---|
连接性 | 面向连接 | 无连接 |
可靠性 | 可靠 | 不可靠 |
有序性 | 有序 | 无序 |
有界性 | 有界 | 无界 |
拥塞控制 | 有 | 无 |
传输速度 | 慢 | 快 |
量级 | 重量级 | 轻量级 |
头部大小 | 大 | 小 |
- TCP 是面向连接的协议,UDP 是无连接协议
TCP 发送数据前使用三次握手建立连接,UDP 发送数据前不需要建立连接。
- TCP 可靠,UDP 不可靠
TCP 丢包会自动重传,UDP 不会(任何必需的可靠性必须由应用层来提供)。 TCP 可靠性由三个机制保证:1. 序号(TCP 报文的序号)2. 确认(ACK 机制)3. 重传(超时或者冗余的 ACK)
- TCP 有序,UDP 无序
消息在传输过程中可能会乱序,后发送的消息可能会先到达,TCP 会对其进行重新排序,UDP 不会。
- TCP 无界,UDP 有界
TCP 通过字节流传输,UDP 中每一个包都是单独的。
- TCP 有流量控制(拥塞控制),UDP 没有
TCP 协议的流量控制是基于滑窗协议实现的。 拥塞控制和流量控制不同,流量控制是点对点的通信量抑制,抑制发送端发送速率,使得接收端来得及接收。
- TCP 传输慢,UDP 传输快;
因为 TCP 需要建立连接、保证可靠性和有序性,所以比较耗时。 这就是为什么视频流、广播电视、在线多媒体游戏等选择使用 UDP。
- TCP 是重量级的,UDP 是轻量级的
TCP 要建立连接、保证可靠性和有序性,就会传输更多的信息,如 TCP 的包头比较大。
UDP如何保证可靠传输(quic)
quic Quick UDP Internet Connection 是一种新的基于UDP的多路复用的安全传输协议,设计目的是对 http/2 语法的优化, 设计时HTTP/2 作为主要的应用层协议,quic 提供了等效 HTTP/2 的多路复用以及流控,等效于 TLS的安全传输,可靠。 以及 TCP 的 拥塞控制
quic 作用于用户空间,现在 chrome 已经内置了 quic 的支持, 因为 quic 是基于用户空间的基于UDP的传输层协议, quic 跟新时不会受到因为各种设备或则中间设备对于新的传输层协议不支持、或者升级缓慢的影响。
首先明确一个概念是 RTT(round-trip time),顾名思义,就是服务器和终端一次交互需要的时间。RTT一般用于衡量网络延迟。
传统的TCP协议,我们需要进行3次握手,也就是1.5 RTT,才开始传输数据。
HTTP/2来说,虽然协议上支持不开启TLS,但是目前大家的实现都是绑定了TLS和HTTP,也就是我们不止要建立连接,还要确定好加密版本,加密密钥等信息,TCP+TLS需要3 RTT。
QUIC 拥塞控制算法主要重新实现了一遍 TCP 的算法,毕竟 TCP 的算法是经过几十年的生产验证的。
多路复用——无队头阻塞版
SPDY 和 HTTP/2 已经实现了多路复用。多路复用的指的是我们不需要在为每个资源重新建立一次 TCP 连接,多个资源的传输可以共用一个连接。
如此一来,在启用了 HTTP/2 的网站,我们再也不需要对资源进行合并了(:)压缩还是可以做一下的),毕竟一次性发出去多个资源和建立多个连接一个一个下载资源相比还是会快一下的。
然后 HTTP/2 的多路复用会有个很大的问题,那就是队头阻塞。原因还是因为 TCP 的 Sequence Number 机制,为了保证资源的有序到达,如果传输队列的队头某个资源丢失了,TCP 必须等到这个资源重传成功之后才会通知应用层处理后续资源。
由于 QUIC 避开了 TCP, 他设计 connection 和 stream 的概念,一个 connection 可以复用传输多个 stream,每个 stream 之间都是独立的,单一一个 stream 丢包并不会影响到其他资源处理。
由于 QUIC 避开了 TCP, 他设计 connection 和 stream 的概念,一个 connection 可以复用传输多个 stream,每个 stream 之间都是独立的,单一一个 stream 丢包并不会影响到其他资源处理。
错误自动纠正
这里的错误指的是某个包丢了。当某个 packet 丢失的时候,QUIC 能够通过已经接收到的其他包对资源进行修复。
这意味着,实际上每个 packet 都携带着多余的信息,通过这些信息,QUIC 能够重组对应资源,而无需进行重传。
目前大概每 10 个包能修复一个 packet。
连接迁移
TCP 是按照 4-要素(客户端IP、端口, 服务器IP、端口) 要确定一个连接的,当这4个要素其中一个发生变化的时候,连接就需要重新建立。而在移动端,我们经常会切换 4G/wifi 使用,每一次切换,我们只能重新建立连接。
在 QUIC 中,连接是由其维护的。 于是 QUIC 通过生成客户端生成一个 Connection ID (64位)的东西来区别不同连接,只要生成的 UUID 不变, 连接就不需要重新建立,即便是客户端的网络发生变化。
引用
https://jaminzhang.github.io/network/The-Difference-Between-TCP-And-UDP-Protocol/
https://genuifx.github.io/2018/11/27/keynote-for-http3-quic/
https://www.nowcoder.com/discuss/714525