本文档整理了后端开发、客户端开发等技术岗位面试中,关于 TCP/IP 协议栈及核心网络协议最常被问到的高频面试题和深度解析。
一、 网络模型基础
1. 讲一下 OSI 七层模型、TCP/IP 四层模型和五层体系结构?
- OSI 七层模型(从上到下):应用层、表示层、会话层、传输层、网络层、数据链路层、物理层。(理论模型,实际未广泛应用)
- TCP/IP 四层模型(从上到下):应用层、传输层、网际层(网络层)、网络接口层。(实际广泛应用的模型)
- 五层体系结构(学习专用,从上到下):应用层、传输层、网络层、数据链路层、物理层。
各层核心功能及常见协议:
- 应用层:为用户提供应用接口,解决特定网络应用问题。(HTTP, HTTPS, FTP, DNS, SMTP, POP3)
- 传输层:为两台主机中的进程提供通用的数据传输服务。(TCP, UDP)
- 网络层:负责为分组交换网上的不同主机提供通信服务,路由选择。(IP, ICMP, ARP, OSPF, BGP)
- 数据链路层:将网络层交下来的 IP 数据报组装成帧,在相邻节点的链路上传送。(以太网协议、PPP)
- 物理层:透明地传送比特流。(RJ45等)
二、 TCP 与 UDP 基础
2. TCP 和 UDP 的区别是什么?
| 特性 | TCP (Transmission Control Protocol) | UDP (User Datagram Protocol) |
|---|---|---|
| 连接性 | 面向连接(需三次握手) | 无连接(直接发) |
| 可靠性 | 可靠传输(不丢包、不乱序) | 不可靠传输(尽最大努力交付,可能丢包) |
| 工作方式 | 字节流(会出现粘包拆包问题) | 数据报文(报文边界明确) |
| 传输效率 | 较慢(开销大,有头部、确认、重传机制) | 较快(开销小) |
| 头部大小 | 至少 20 字节,可变 | 8 字节(固定) |
| 拥塞控制/流量控制 | 有 | 无 |
| 适用场景 | 文件传输、HTTP/HTTPS、邮件(要求准确无误) | 视频流媒体、直播、DNS查询、实时游戏(要求实时性) |
- 补充:TCP 是面向进程的连接,而 UDP 是面向主机的无连接协议。
- TCP 通过序列号、确认应答、重传机制保证可靠性,而 UDP 则不提供这些机制,完全依赖应用层来处理丢包和乱序问题。
- TCP 的头部包含更多字段(如序列号、确认号、窗口大小等)来支持可靠传输和流量控制,而 UDP 的头部非常简洁,仅包含源端口、目的端口、长度和校验和。
- 粘包拆包问题:TCP 是字节流协议,发送方连续发送多个报文时,接收方可能会将它们合并成一个报文(粘包)或将一个报文分成多个部分接收(拆包)。这可能会导致数据解析问题。UDP 是数据报协议,每个报文独立传输,不存在粘包拆包问题。
三、 TCP 连接管理(绝对重点)
3. 请详细画出/描述 TCP 的三次握手过程?
三次握手是为了建立可靠的连接,同步双方的序列号和窗口大小。
- 第一次握手(Client -> Server):客户端生成一个随机序列号 seq = x,并把标志位 SYN 设为 1。客户端进入 SYN_SENT 状态。此时报文不携带数据。
- 第二次握手(Server -> Client):服务端收到 SYN 报文,同意建立连接,生成自己的随机序列号 seq = y,并将确认号 ack = x + 1,同时将 SYN 和 ACK 标志位都设为 1。服务端进入 SYN_RCVD 状态。
- 第三次握手(Client -> Server):客户端收到服务端的 SYN+ACK 报文,检查 ack 是否为 x+1。如果正确,则将标志位 ACK 设为 1,确认号 ack = y + 1。客户端进入 ESTABLISHED 状态。服务端收到后也进入 ESTABLISHED 状态,连接建立。此报文可以携带数据。
4. 为什么是三次握手?两次不行吗?四次不行吗?
- 为什么不能是两次?(防止已失效的连接请求报文段突然又传送到了服务端)
假设客户端发送了第一个 SYN 报文(因为网络延迟滞留了),客户端超时后重发了第二个 SYN 并完成了两次握手建立连接,数据传完后断开。此时,第一个滞留的 SYN 终于到了服务端。如果是两次握手,服务端会以为客户端又要建立连接,直接单方面进入 ESTABLISHED 状态并分配资源,导致服务端资源浪费(即“历史连接”问题)。三次握手可以让客户端在第三步拒绝这个历史连接。 - 为什么不需要四次?
服务端的确认报文(ACK)和同步报文(SYN)是可以合并在一起发送的(即第二次握手),没必要拆成两步,所以三次足够了。
5. 请详细画出/描述 TCP 的四次挥手过程?
由于 TCP 是全双工的,因此每个方向都必须单独进行关闭。
- 第一次挥手(Client -> Server):客户端应用进程发出连接释放报文,FIN = 1, seq = u。客户端进入 FIN_WAIT_1 状态。表示客户端没有数据要发了。
- 第二次挥手(Server -> Client):服务端收到 FIN,发出确认报文 ACK = 1, ack = u + 1, seq = v。服务端进入 CLOSE_WAIT 状态。此时 TCP 连接处于半关闭状态,客户端不能发数据,但服务端如果还有数据没发完,可以继续发。客户端收到 ACK 后进入 FIN_WAIT_2 状态。
- 第三次挥手(Server -> Client):服务端数据发送完毕,发出连接释放报文,FIN = 1, ACK = 1, seq = w, ack = u + 1。服务端进入 LAST_ACK 状态。
- 第四次挥手(Client -> Server):客户端收到 FIN 后,发出确认报文 ACK = 1, ack = w + 1, seq = u + 1。客户端进入 TIME_WAIT 状态。服务端收到 ACK 后进入 CLOSED 状态。客户端经过 2MSL 时间后,也进入 CLOSED 状态。
6. 为什么挥手需要四次,而握手只需要三次?
因为 TCP 是全双工通信。握手时,服务端的 SYN 和 ACK 可以一起发送。但挥手时,当收到对方的 FIN 报文时,仅仅表示对方不再发送数据了,但接收方自己可能还有数据需要发送。所以接收方先回复一个 ACK,等自己数据发送完毕后,再发送 FIN 报文。因此通常需要四次。
7. 什么是 TIME_WAIT 状态?为什么需要等待 2MSL?
TIME_WAIT 是主动关闭连接的一方在发送完最后一个 ACK 后进入的状态。等待 2MSL(最大报文生存时间的2倍)原因有二:
- 保证可靠关闭:如果最后的 ACK 丢失,服务端会重传 FIN。客户端在 2MSL 内可再次收到 FIN 并重发 ACK。重发之后 TIME_WAIT 计时器重置,继续等待,直到 2MSL 超时后才真正关闭连接。
- 防止“已失效报文”干扰:保证本次连接的所有报文从网络中消失,不会影响后续的新连接。
8. 为什么 TIME_WAIT 的时间是 2MSL?为什么不是 MSL 或者 3MSL?
MSL 是指网络中一个报文的最大生存时间。等待 2MSL 的原因是:
- 保证可靠关闭:如果最后的 ACK 丢失,服务端会重传 FIN。客户端在 2MSL 内可再次收到 FIN 并重发 ACK。重发之后 TIME_WAIT 计时器重置,继续等待,直到 2MSL 超时后才真正关闭连接。
- 防止“已失效报文”干扰:保证本次连接的所有报文从网络中消失,不会影响后续的新连接。 如果只等待 MSL,可能会有未消失的报文干扰后续连接;如果等待 3MSL,虽然更安全,但会增加资源占用和连接关闭的延迟,2MSL 是一个权衡的选择。
9. TIME_WAIT 状态会导致什么问题?如何解决?
TIME_WAIT 状态会导致服务器资源被占用,尤其是在高并发场景下,可能出现大量 TIME_WAIT 连接,导致服务器无法接受新的连接请求(即“端口耗尽”问题)。解决方法有:
- 调整操作系统参数:如 Linux 中可以通过修改
/proc/sys/net/ipv4/tcp_tw_reuse和/proc/sys/net/ipv4/tcp_tw_recycle来允许重用 TIME_WAIT 状态的连接(但这可能会引入安全风险)。 - 使用负载均衡:将请求分散到多个服务器上,减少单台服务器的连接压力。
- 优化应用层协议:如使用 HTTP/2 的长连接,减少连接的建立和关闭次数。
- 使用 UDP:对于一些不需要可靠传输的场景,可以考虑使用 UDP,避免 TCP 的连接管理开销。
四、 TCP 可靠传输与控制
10. TCP 是如何保证可靠传输的?
TCP 保证可靠传输主要依靠:
- 数据分块与校验和:验证数据在传输过程中是否损坏。
- 序列号与确认应答 (Seq & ACK):保证数据不乱序、不丢失。
- 超时重传机制:未在 RTO(Retransmission Timeout,超时重传时间) 内收到 ACK,则重新发送。
- 连接管理:三次握手、四次挥手。
- 流量控制(滑动窗口):控制发送速度,防止接收缓冲区溢出。
- 拥塞控制:网络拥塞时减少发送量。
11. 详细说说 TCP 的拥塞控制?
拥塞控制包含四个算法:
- 慢启动:刚建立连接时,拥塞窗口 cwnd 较小,随后每经过一个 RTT 呈指数级增长,直到达到阈值 ssthresh。
- 拥塞避免:当 cwnd >= ssthresh 时,每经过一个 RTT cwnd 加 1,呈线性增长。
- 快速重传:收到连续 3 个相同的重复 ACK 时,立刻重传丢失报文,不等待超时。
- 快速恢复:配合快速重传,将 ssthresh 减半,cwnd 设为 ssthresh,进入拥塞避免阶段。(注:超时丢包通常回退到慢启动)
- 为什么收到连续 3 个重复 ACK 就认为丢包了?因为 TCP 是基于 ACK 来确认数据的,如果连续收到 3 个相同的 ACK,说明后续的数据包已经到达了,但某个数据包丢失了,导致 ACK 没有更新。这个机制比等待超时更快地检测到丢包,提高了传输效率。
五、 网络层与其他核心协议
12. IP 协议是干什么的?IPv4 和 IPv6 的区别?
IP 协议负责在网络中进行路由寻址和数据包的分片。它提供了无连接、不可靠的服务,数据包可能会丢失、重复或乱序,可靠性由传输层(如 TCP)保证。
- IPv4:32 位地址,资源已枯竭。
- IPv6:128 位地址,号称“给地球上每一粒沙子分配一个 IP”。简化了头部,原生支持 IPSec,安全性更高。
13. ARP 协议的作用是什么?
将 IP 地址转换为 MAC 地址。通过局域网广播请求,目标主机单播回复。
六、 应用层协议核心(HTTP / HTTPS / DNS)
14. HTTP 1.0、1.1、2.0、3.0 的主要区别是什么?
HTTP 是基于 TCP 的应用层协议,随着互联网的发展不断演进:
- HTTP 1.0:默认短连接(每次请求都需建立 TCP 连接),存在队头阻塞问题。
- HTTP 1.1:默认长连接(Keep-Alive),引入了管道化机制(但存在服务端的队头阻塞),增加了缓存控制(Cache-Control)、断点续传(Range 头部)等功能。
- HTTP 2.0:
- 多路复用:一个 TCP 连接上可以并发交错发送多个请求/响应(彻底解决 HTTP 层的队头阻塞)。
- 二进制分帧:数据解析更高效。
- 头部压缩(HPACK):减少传输体积。
- 服务端推送(Server Push):服务端可以主动向客户端推送资源。
- HTTP 3.0:
- 基于 QUIC 协议(底层为 UDP):彻底解决了 TCP 级别的队头阻塞问题。
- 连接迁移:基于连接 ID 而非 IP+端口 识别连接,切换网络(如 Wi-Fi 换到 4G)时连接不断开。
| 版本 | 连接方式 | 队头阻塞 | 主要特性 |
|---|---|---|---|
| HTTP 1.0 | 短连接 | 存在 | 无管道化 |
| HTTP 1.1 | 长连接 | 存在 | 管道化、缓存控制、断点续传 |
| HTTP 2.0 | 长连接 | 解决 | 多路复用、二进制分帧、头部压缩、服务端推送 |
| HTTP 3.0 | 基于 QUIC(UDP) | 彻底解决 | 连接迁移 |
- 补充:对头阻塞问题的理解:HTTP 1.x 中,如果一个请求被阻塞了(如服务器处理慢),后续的请求即使已经到达服务器,也无法得到响应,因为它们都在同一个 TCP 连接上排队等待前一个请求完成。而 HTTP 2.0 和 HTTP 3.0 通过多路复用和基于 UDP 的 QUIC 协议,彻底解决了这个问题,使得每个请求都可以独立处理,不受其他请求的影响。
15. GET 和 POST 的区别?
| 特性 | GET | POST |
|---|---|---|
| 语义 | 获取资源(读取) | 提交/修改资源(写入) |
| 参数位置 | 放在 URL 中(?key=value) | 放在 HTTP 报文的 Body(请求体)中 |
| 安全性 | 较低(参数暴露在 URL,可被浏览器历史记录保存) | 相对较高(参数在 Body 中,但不加密仍可抓包) |
| 长度限制 | 受限于浏览器和服务器对 URL 长度的限制 | 理论上无限制(受限于服务器配置) |
| 幂等性 | 幂等(执行多次结果相同) | 不幂等(执行多次可能会创建多个资源) |
| 缓存 | 浏览器默认会缓存 GET 请求 | 浏览器默认不会缓存 POST 请求 |
- 补充:幂等性是指无论执行多少次,结果都是一样的。GET 请求通常用于获取数据,不会对服务器资源造成修改,因此是幂等的。而 POST 请求通常用于提交数据或修改资源,每次执行可能会创建新的资源或修改现有资源,因此不是幂等的。
16. HTTP 常见的状态码有哪些?
- 2xx (成功):
- 200 OK:请求成功。
- 204 No Content:请求成功,但响应报文不包含实体的主体部分。
- 206 Partial Content:客户端进行了范围请求(断点续传),服务器成功执行。
- 3xx (重定向):
- 301 Moved Permanently:永久重定向(资源换了新 URL)。
- 302 Found:临时重定向。
- 304 Not Modified:资源未修改,走协商缓存(非常重要,面试常考浏览器缓存机制)。
- 4xx (客户端错误):
- 400 Bad Request:请求报文有语法错误。
- 401 Unauthorized:请求需要认证信息。
- 403 Forbidden:服务器拒绝访问(通常是权限不足)。
- 404 Not Found:找不到请求的资源。
- 5xx (服务器错误):
- 500 Internal Server Error:服务器内部错误(代码抛异常了)。
- 502 Bad Gateway:网关或代理服务器收到无效响应(常见于 Nginx 转发给后端服务失败)。
- 504 Gateway Timeout:网关超时(后端服务处理太慢)。
17. HTTPS 的工作原理是什么?(详细描述 TLS/SSL 握手过程)
HTTPS = HTTP + SSL/TLS。它通过非对称加密协商密钥,再通过对称加密传输数据,并利用数字证书验证身份。
SSL/TLS (Secure Sockets Layer / Transport Layer Security)是安全套接字层协议,TLS 是 SSL 的升级版本,SSL 3.0 之后就没有继续发展了。
简化的 TLS 1.2 握手过程如下:
- Client Hello:客户端向服务端发送自己支持的 TLS 版本、加密套件列表,以及一个客户端随机数 (Random1)。
- Server Hello:服务端确认 TLS 版本和加密套件,发送一个服务端随机数 (Random2),并把包含公钥的数字证书发送给客户端。
- 客户端验证证书:客户端确保证书是由权威 CA 签发的,域名一致且未过期。
- 生成 Pre-Master Secret:客户端生成一个新的随机数 Pre-Master Secret,用证书里的公钥进行加密,发送给服务端。
- 服务端解密:服务端用自己的私钥解密,得到 Pre-Master Secret。
- 生成最终对称密钥 (Master Secret):此时双方都有了 Random1、Random2 和 Pre-Master Secret,双方使用相同的算法计算出最终的对称密钥(会话密钥)。
- 加密通信:后续的 HTTP 数据传输全部使用这个对称密钥进行加密和解密。
18. DNS 的解析过程是怎样的?为什么 DNS 既使用 TCP 又使用 UDP?
- 解析过程(浏览器输入域名后):
- 查浏览器缓存。
- 查操作系统缓存(如 hosts 文件)。
- 查本地 DNS 服务器(通常由 ISP 提供,这步是递归查询)。
- 本地 DNS 服务器依次向根域名服务器 -> 顶级域名服务器 (.com) -> 权威域名服务器 发起迭代查询,最终获取 IP 并返回给客户端。
- TCP 还是 UDP?
- 默认使用 UDP (端口 53):因为一次 UDP 请求和响应就能完成,无连接、速度快、负载低。
- 使用 TCP 的场景:
- 当响应报文大小超过 512 字节时(为了防止 UDP 报文被截断)。
- DNS 服务器之间进行区域传送(主从 DNS 数据同步)时,因为需要传输大量数据,必须保证可靠性,所以使用 TCP。
七、 综合场景题
19. 【经典终极必考题】在浏览器中输入 URL 到页面显示,经历了什么过程?
这是一个贯穿整个网络体系的题目,必须对答如流:
- URL 解析:浏览器解析 URL,确定协议(HTTP/HTTPS)、域名、端口、路径。
- DNS 域名解析:依次查找各级缓存及 DNS 服务器,最终得到目标 IP 地址。
- 建立 TCP 连接:浏览器与目标服务器发起 TCP 三次握手。
- TLS 握手(如果是 HTTPS):进行密钥协商,验证证书,建立加密通道。
- 发送 HTTP 请求:浏览器构建 HTTP 请求报文并发送。
- 服务器处理并响应:服务器接收请求,由 Web Server(如 Nginx, Tomcat)处理,返回 HTTP 响应报文。
- 浏览器渲染页面:解析 HTML/CSS,生成 DOM 树和 CSSOM 树,合并为渲染树,布局并绘制到屏幕上。
- 断开 TCP 连接:通过 TCP 四次挥手释放连接(若为 Keep-Alive 则暂时保持)。





