Skip to content

TCP、UDP 与 DNS ​

问题 ​

TCP 和 UDP 有什么区别?TCP 三次握手/四次挥手是怎么进行的?DNS 如何解析域名?OSI 七层模型和 TCP/IP 五层模型分别是什么?

结论 ​

TCP vs UDP 对比 ​

维度UDPTCP
连接无连接(直接发)面向连接(三次握手)
可靠性不可靠(不确认、不重传)可靠(确认、重传、排序)
传输对象一对一/一对多/多对多只支持一对一
传输方式面向报文(保留边界)面向字节流(无边界)
头部开销8 字节最小 20 字节
速度快(无握手和确认开销)慢(控制机制多)
适用场景实时音视频、直播、DNS 查询文件传输、网页、数据库

为什么 UDP 不可靠:发送后不确认、不重传、无超时、不排序、无拥塞控制,"发出去就完事了"。

TCP 三次握手 ​

建立 TCP 连接需要 3 次包交换,目的是双方确认各自的发送/接收能力正常,并同步初始序号(ISN):

客户端                           服务端
  |  → SYN (seq=x)                |   第1次:客户端发起连接请求
  |  ← SYN+ACK (seq=y, ack=x+1)  |   第2次:服务端确认并同步自己的序号
  |  → ACK (ack=y+1)              |   第3次:客户端确认服务端的序号
  |         双方 ESTABLISHED       |

为什么需要三次?两次不够:

  • 两次握手时服务端无法确认自己的序号是否被客户端收到
  • 若第一次 SYN 在网络中延误,到连接释放后才到达,服务端若直接建立连接会造成资源浪费

TCP 四次挥手 ​

关闭 TCP 连接需要 4 次包交换,因为 TCP 是全双工的,双方各需独立关闭自己的发送方向:

客户端(先关)                    服务端
  |  → FIN (seq=u)                |   第1次:客户端要求断开(停止发数据)
  |  ← ACK (ack=u+1)              |   第2次:服务端确认(服务端仍可能发数据)
  |  ← FIN (seq=w, ack=u+1)       |   第3次:服务端数据发完后,也要求断开
  |  → ACK (ack=w+1)              |   第4次:客户端确认(进入 TIME-WAIT)
  |    2MSL 后 → CLOSED            |

TIME-WAIT 状态:客户端第 4 次挥手后等待 2MSL(最大报文生存时间),防止最后一个 ACK 丢失后服务端重发 FIN 找不到应答。

为什么需要四次?:服务端收到 FIN 时可能还有数据要发,必须先 ACK 确认,等数据发完再发 FIN,所以无法合并。

DNS 协议 ​

作用:将域名转换为 IP 地址(应用层协议,53 端口)。

TCP 还是 UDP:

  • DNS 查询用 UDP:响应包通常 < 512 字节,无需三次握手,响应更快
  • 区域传送(同步数据库)用 TCP:数据量大,需要可靠传输

DNS 完整查询过程(7步):

  1. 浏览器缓存查找
  2. 操作系统缓存(hosts 文件等)
  3. 本地 DNS 服务器缓存查找
  4. 本地 DNS 向根域名服务器查询,得到顶级域名服务器(TLD)地址
  5. 向 TLD 服务器查询(如 .com),得到权威域名服务器地址
  6. 向权威域名服务器查询,得到目标 IP 地址
  7. 本地 DNS 缓存结果并返回给浏览器

递归查询 vs 迭代查询:

  • 用户 → 本地 DNS:递归查询(用户只发一次请求,本地 DNS 代为查询到底)
  • 本地 DNS → 各级 DNS:迭代查询(每次只返回下一级 DNS 地址,本地 DNS 自己继续查)

OSI 七层模型 vs TCP/IP 五层模型 ​

OSI 七层TCP/IP 五层典型协议
应用层应用层HTTP、HTTPS、FTP、DNS、SMTP
表示层↑(合并入应用层)SSL/TLS、编码/压缩
会话层↑(合并入应用层)—
传输层传输层TCP、UDP
网络层网络层IP、ICMP
数据链路层数据链路层Ethernet、Wi-Fi(IEEE 802.11)
物理层物理层光纤、网线、无线电信号

TCP/IP 五层将 OSI 的应用层/表示层/会话层合并为应用层,更符合实际网络实现。

常见面试问法:HTTP 是应用层协议,基于传输层的 TCP;IP 是网络层协议;TCP/UDP 工作在传输层;浏览器 URL 解析 → DNS → TCP → HTTP 是跨三层协议的协作。

TCP 的重传机制 ​

TCP 下层网络可能出现丢失、重复或失序,TCP 提供可靠传输服务。TCP 使用两套机制完成重传:

  1. 基于时间:TCP 发送数据后开启定时器,若在规定时间内未收到 ACK 确认,则对该报文重传;达到一定次数仍失败则发送复位信号。
  2. 基于确认信息:收到 3 个重复 ACK(快速重传),立即重传而不等待定时器超时。

TCP 的拥塞控制机制 ​

TCP 拥塞控制主要有四种机制:

① 慢启动(Slow Start)

  • 初始拥塞窗口 cwnd = 1,指数增长(每 RTT 翻倍)
  • 设置慢启动门限(ssthresh):cwnd < ssthresh 时用慢启动,cwnd >= ssthresh 时改用拥塞避免

② 拥塞避免

  • cwnd 线性增长(每 RTT 加 1),使网络不容易出现拥塞
  • 一旦检测到拥塞(超时),ssthresh = cwnd / 2,cwnd 重置为 1,重新慢启动

③ 快速重传(Fast Retransmit)

  • 接收方收到乱序报文段后立即发送重复确认(Duplicate ACK)
  • 发送方连续收到 3 个重复 ACK 后,立即重传丢失的报文段,无需等待定时器

④ 快速恢复(Fast Recovery)

  • 收到 3 个重复 ACK 后:ssthresh = cwnd / 2,cwnd = ssthresh(不重置为 1)
  • 直接进入拥塞避免阶段,避免慢启动带来的吞吐量骤降

TCP 的流量控制机制 ​

流量控制的目的是让发送方不要发太快,让接收方来得及接收。TCP 采用滑动窗口机制:

  • 连接建立时,双方各分配缓冲区并将大小告知对方(接收窗口)
  • 数据到达时,接收方在 ACK 中携带剩余缓冲区大小(窗口通告)
  • 若接收方缓冲区满,通告零窗口,发送方必须停止发送,直到收到正窗口通告
  • 发送窗口大小 = min(接收窗口, 拥塞窗口)

TCP 的可靠传输机制 ​

TCP 可靠传输基于连续 ARQ 协议和滑动窗口协议:

  • 发送方维护发送窗口,依次发送窗口内所有报文段,并设置定时器
  • 收到 ACK 后滑动窗口;定时器超时则重传所有已发但未确认的报文段(超时间隔翻倍)
  • 收到 3 个冗余 ACK 触发快速重传
  • 接收方使用累计确认:ACK 表示该序号之前的报文段均已按序到达
  • 实际 TCP 会缓存乱序报文段,丢包重传时只重传丢失的那一个(结合选择重传)

TCP 粘包是怎么回事,如何处理 ​

TCP 默认启用 Nagle 算法(延迟传送),将短时间内多次发送的数据缓冲合并一次发出,导致接收端可能一次收到多个消息合并在一起(粘包)。

粘包情况:

  • 发送 data1、data2,可能接收到的是 data1 的部分 + data2 全部(或其他组合)

处理方案:

  1. 发送间隔等待:两次发送之间加等待时间(适用于低频交互,性能差)
  2. 关闭 Nagle 算法:通过 socket.setNoDelay() 禁用,让每次发送立即传出(适用于数据量较大、频率不高的场景)
  3. 封包/拆包:在数据包前后加特征标识符,接收端根据特征标识拆分各数据包(业界主流方案)

为什么 UDP 不会粘包 ​

  • TCP 是面向流协议,数据无边界,Nagle 等机制会合并小包,接收端无法区分消息边界
  • UDP 是面向消息协议,每个 UDP 报文就是一条独立消息,有消息头(来源地址、端口等),接收端以消息为单位提取,天然有消息边界
  • UDP 接收端一次只能接收发送端发出的一个数据包,数据过大会丢失部分,但不会"合并"

DNS 记录和报文 ​

DNS 服务器以**资源记录(Resource Record)**形式存储信息,格式为:

(Name, Value, Type, TTL)

TTL 是资源记录的生存时间,定义了其他 DNS 服务器可以缓存该记录多久。

常用 Type 值:

TypeNameValue说明
A主机名IP 地址标准的主机名到 IP 映射
NS域名负责该域名的 DNS 服务器主机名DNS 链式查询时指向下一级 DNS
CNAME别名规范主机名为复杂主机名提供便于记忆的别名
MX邮件服务器别名邮件服务器规范主机名邮件路由

参考来源 ​