为什么 DNS 协议使用 UDP 呢?这个问题可能大部分同学在各种博客或者面试过程中都或多或少遇见过,张口就来,UDP 快啊,DNS 使用 UDP 使得打开网页速度更快。
那各位有没有想过,既然 UDP 更快,为什么 HTTP 不使用 UDP 呢?
另外,为什么 DNS 协议使用 UDP 这个问题本身其实并不完全正确,DNS 并非只使用 UDP 协议,它同时占用了 UDP 和 TCP 的 53 端口,作为单个应用层的协议,DNS 同时使用两种传输协议也属实是个另类了。
DNS 为什么同时使用 TCP 和 UDP
我们从 TCP 与 UDP 的比较说起,老生常谈的话题,不过相信大部分同学都会忽略掉一个点,等下会指出来。
OK,轻松环节,闭着眼睛背:
1)TCP 需要三次握手建立连接,四次挥手释放连接;UDP 不需要,面向无连接
2)TCP 首部需要 20 个字节;而 UDP 首部只有 8 个字节
3)TCP 具有一系列保证可靠传输的机制;而 UDP 尽最大努力交付,不提供可靠传输的机制,如果在数据传输的过程中出现部分数据的丢失,UDP 协议本身并不能做出任何检测或补救措施
4)正是由于 UDP 没有了可靠传输机制,所以速度远远快于 TCP,在某些情况下 UDP 是一种最有效的工作方式,一般用于即时通信,比如:语音电话、 直播等等;而 TCP 一般用于文件传输、发送和接收邮件、远程登录等准确性要求比较高的场景
上面这些是最基本的吧。
接下来讲的这个点,也就是很多人容易忽略的点,和 DNS 为什么需要同时使用 UDP 和 TCP 这个问题息息相关:
- 那就是 TCP 是面向字节流的,而 UDP 是面向报文的
解释一下这句话,我们知道,TCP 具有序列号机制,发送方会把一个大的 HTTP 报文按序号分割成若干报文段并加上 TCP 首部,也就是封装成 TCP 报文段。那么接收方在收到这些 TCP 报文段后,就会按照序号以原来的顺序重组 HTTP 报文。这就是面向字节流的 TCP。
而所谓 UDP 面向报文,发送方的 UDP 对应用层交付下来的 HTTP 报文, 在添加 UDP 首部后也就是封装成 UDP 报文,就向下交付给网络层 IP 协议。不做任何的拆分与合并,主要就是因为 UDP 没有像 TCP 一样的序列号机制来标识报文,所以默认只有一个 UDP 报文。
UDP 这么做就会导致一个问题。
互联网上物理链路的最小传输单元 = 576 字节,为了在物理链路上顺利传输,UDP 报文不能超过 576 字节,为此,UDP 报文被限制在 512 字节以内。
而 DNS 由于大面积使用了 UDP,这样一旦 DNS 报文超过 512 字节,基于 UDP 的 DNS 报文就只有抛弃多出来的 64 字节,截短为 512 字节,那么用户得到的 DNS 报文就是不完整的。
如何解决这个问题呢?