实际上DNS协议同时采用了UDP和TCP两种传输层协议。他同时占用了UDP和TCP的53端口。那么这个问题就变成了为什么DNS同时使用了UDP和TCP两种传输层协议?
首先对于TCP协议来说,在进行请求和响应前后需要进行连接的建立,即TCP需要进行三次握手建立连接,四次挥手释放连接。相对于UDP而言,UDP不用进行连接的建立和释放,在这一步加快了请求响应的时间。再者TCP首部需要20个字节,而UDP的首部只有8字节,从数据的传输上考虑当然UDP的效率更高。并且TCP具有一些一的可靠传输机制,在保证数据的可靠性前提下,会耗费一定的资源对数据进行校验。而UDP只保证了请求尽最大努力交付,不提供可靠传输机制,如果在数据传输的过程中出现部分数据的丢失,UDP 协议本身并不能做出任何检测或补救措施。正是由于 UDP 没有了可靠传输机制,所以速度远远快于 TCP。
这就是为什么DNS协议偏向使用UDP的原因,那么为什么还要采用TCP也作为传输层协议呢?
首先,TCP是面向字节流的,UDP面向报文。TCP具有序列号机制,发送方会把一个大的HTTP报文按序号分割成若干报文段并加上TCP首部,封装成为TCP报文段。接收方在收到这些报文段之后,就会按照序列号按照原来的顺序重组HTTP报文。
而UDP面向报文,发送方的UDP对应用层交付下来的HTTP报文,在添加了UDP首部后,封装成为UDP报文后,就交付给下层IP协议。不对应用层交付下来的报文进行任何拆分和合并。
互联网上物理链路的最小传输单元 = 576 字节,为了在物理链路上顺利传输,UDP 报文不能超过 576 字节,为此,UDP 报文被限制在 512 字节以内。
而 DNS 由于大面积使用了 UDP,这样一旦 DNS 报文超过 512 字节,基于 UDP 的 DNS 报文就只有抛弃多出来的 64 字节,截短为 512 字节,那么用户得到的 DNS 报文就是不完整的。