计网
网络模型
OSI 七层模型是什么?每⼀层的作⽤是什么?
OSI失败的原因:
-
OSI 的专家缺乏实际经验,他们在完成 OSI 标准时缺乏商业驱动⼒
-
OSI 制定标准的周期太⻓,因⽽使得按 OSI 标准⽣产的设备⽆法及时进⼊市场
-
OSI 的协议实现起来过分复杂,⽽且运⾏效率很低
-
OSI 的层次划分不太合理,有些功能在多个层次中重复出现

TCP/IP 四层模型是什么?每⼀层的作⽤是什么?
TCP/IP 四层模型 是⽬前被⼴泛采⽤的⼀种模型,我们可以将 TCP / IP 模型看作是 OSI 七层模型的精 简版本,由以下 4 层组成:
- 应⽤层 2. 传输层 3. ⽹络层 4. ⽹络接⼝层
应⽤层(Application layer) 应⽤层位于传输层之上,给用户提供服务、提供接口、决定用户怎么和网络交互。

传输层(Transport layer) 传输层的主要任务负责数据是否可靠、是否完整、是否按顺序到达。

⽹络层(Network layer) ⽹络层负责找到目标主机在哪、选择最佳路径把数据包送过去。

我们可以把⽹络接⼝层看作是数据链路层和物理层的合体。把数据变成电信号 / 光信号,在物理网络上传输。
-
数据链路层(data link layer)通常简称为链路层( 两台主机之间的数据传输,总是在⼀段⼀段的 链路上传送的)。数据链路层的作⽤是将⽹络层交下来的 IP 数据报组装成帧,在两个相邻节点 间的链路上传送帧。每⼀帧包括数据和必要的控制信息(如同步信息,地址信息,差错控制 等)。
-
物理层的作⽤是实现相邻计算机节点之间⽐特流的透明传送,尽可能屏蔽掉具体传输介质和物理 设备的差异

各个协议的作用
应用层协议(给用户 / 程序提供服务)
HTTP:网页浏览、接口通信,浏览器和服务器交互用。
DHCP:自动给电脑 / 手机分配 IP 地址、子网掩码、网关。
DNS :把域名(如 www.baidu.com)翻译成 IP 地址。
FTP:文件上传、下载专用协议。
Telnet:远程登录设备,纯文本命令行控制。
SMTP:发邮件。
POP3 / IMAP:收邮件。
传输层协议(端到端传输、保证可靠 / 效率)
TCP:可靠传输,不丢包、不乱序,有流量控制、拥塞控制,用于 HTTP、邮件等。
UDP:快速、简单、不可靠,用于直播、视频、游戏、DNS 查询。
RDT:可靠数据传输机制(理论协议,保证数据正确送达)。
网络层协议(负责寻址、路由、跨网传输)
IP:定义地址,负责把数据包从源主机送到目标主机。
ARP:通过 IP 找 MAC 地址(局域网内定位设备)。
ICMP:网络诊断,ping 命令用的就是它。
NAT:多台设备共用一个公网 IP 上网。
RIP / OSPF:内网路由器之间学习路径。
BGP:不同运营商 / 公司之间交换路由。
网络接口层(负责在同一局域网内传输)
MAC 协议:设备物理地址,唯一标识网卡。
CSMA/CD:以太网里避免多设备同时发送冲突。
差错检测:检查传输中数据是否出错。
多路访问:多设备共享一条信道。
以太网技术:局域网最主流的传输标准。
为什么需要分层
1.通过分层将大问题化小,让每⼀层都需要专注于⼀类事情。使得复杂的计算机⽹络系统变得易于设计,实现和标准化。
2.提高整体灵活性,每⼀层都可以使⽤最适合的技术来实现,只需要保证每层提供的功能以及 暴露的接⼝的规则没有改变就⾏了。
从输入URL 到页面展示到底发生了什么?
-
解析URL:分析 URL 所需要使用的传输协议和请求的资源路径。如果输入的 URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。如果没有问题,浏览器会检查 URL 中是否出现了非法字符,则对非法字符进行转义后在进行下一过程。
-
缓存判断:浏览器缓存 → 系统缓存(hosts 文件) → 路由器缓存 → ISP 的 DNS 缓存,如果其中某个缓存存在,直接返回服务器的IP地址。
-
DNS解析:如果缓存未命中,浏览器向本地 DNS 服务器发起请求,最终可能通过根域名服务器、顶级域名服务器(.com)、权威域名服务器逐级查询,直到获取目标域名的 IP 地址。
-
获取MAC地址:先判断是否与请求主机在同一个子网里,如果在同一个子网里,可以使用 ARP 协议获取到目的主机的 MAC 地址,如果不在一个子网里,那么请求应该转发给网关,由它代为转发,此时同样可以通过 ARP 协议来获取网关的 MAC 地址,此时目的主机的 MAC 地址应该为网关的地址。
-
建立TCP连接:主机将使用目标 IP地址和目标MAC地址发送一个TCP SYN包,请求建立一个TCP连接,然后交给路由器转发,等路由器转到目标服务器后,服务器回复一个SYN-ACK包,确认连接请求。然后,主机发送一个ACK包,确认已收到服务器的确认,然后 TCP 连接建立完成。
-
HTTPS 的 TLS 四次握手:如果使用的是 HTTPS 协议,在通信前还存在 TLS 的四次握手。
-
发送HTTP请求:连接建立后,浏览器会向服务器发送HTTP请求。请求中包含了用户需要获取的资源的信息,例如网页的URL、请求方法(GET、POST等)等。
-
服务器处理请求并返回响应:服务器收到请求后,会根据请求的内容进行相应的处理。例如,如果是请求网页,服务器会读取相应的网页文件,并生成HTTP响应。
应用层
HTTP报文有哪些部分?
请求报文:
-
请求行:包含HTTP协议版本,请求方法、请求目标(URL或URI)。
-
请求头部:包含关于请求的附加信息,如Host(指定请求的目标域名 + 端口)、User-Agent(标识客户端类型)、Content-Type(请求体的数据类型)、Connection(标识长连接 / 短连接)等。
-
空行:请求头部和请求体之间用空行分隔。
-
请求体:可选,包含请求的数据,通常用于POST请求等需要传输数据的情况。
响应报文:
-
状态行:包含HTTP协议版本、状态码和状态信息。
-
响应头部:包含关于响应的附加信息,如Content-Type、Content-Length等。
-
空行:响应头部和响应体之间用空行分隔。
-
响应体:包含响应的数据,通常是服务器返回的HTML、JSON等内容。
HTTP 状态码有哪些?

200 OK:请求被成功处理。例如,发送一个查询用户数据的 HTTP 请求到服务端,服务端正确返回了用户数据。这个是我们平时最常见的一个 HTTP 状态码。
201 Created:请求被成功处理并且在服务端创建了一个新的资源。例如,通过 POST 请求创建一个新的用户。
202 Accepted:服务端已经接收到了请求,但是还未处理。例如,发送一个需要服务端花费较长时间处理的请求(如报告生成、Excel 导出),服务端接收了请求但尚未处理完毕。
204 No Content:服务端已经成功处理了请求,但是没有返回任何内容。例如,发送请求删除一个用户,服务器成功处理了删除操作但没有返回任何内容
301 Moved Permanently:资源被永久重定向了。比如你的网站的网址更换了。
302 Found:资源被临时重定向了。比如你的网站的某些资源被暂时转移到另外一个网址
400 Bad Request:发送的 HTTP 请求存在问题。比如请求参数不合法、请求方法错误。
401 Unauthorized:请求需要认证之后才能访问的资源。
403 Forbidden:直接拒绝 HTTP 请求,不处理。一般用来针对非法请求。
404 Not Found:你请求的资源未在服务端找到。比如你请求某个用户的信息,服务端并没有找到指定的用户。
409 Conflict:表示请求的资源与服务端当前的状态存在冲突,请求无法被处理
500 Internal Server Error:服务端出问题了(通常是服务端出 Bug 了)。比如你服务端处理请求的时候突然抛出异常,但是异常并未在服务端被正确处理。
502 Bad Gateway:我们的网关将请求转发到服务端,但是服务端返回的却是一个错误的响应。
HTTP和HTTPS 的区别?
区别主要有以下四点:
-
HTTP 是超文本传输协议,信息是明文传输,存在安全风险 的问题。HTTPS 则解决 HTTP 不安全的缺陷,在 TCP 和 HTTP 网络层之间加入了 SSL/TLS 安全协议,使得报文能够加密传输。
-
HTTP 连接建立相对简单, TCP 三次握手之后便可进行 HTTP 的报文传输。而 HTTPS 在 TCP 三次握手之后,还需进行 SSL/TLS 的握手过程,才可进入加密报文传输。
-
两者的默认端口不一样,HTTP 默认端口号是 80,HTTPS 默认端口号是 443。
-
HTTPS 协议需要向 CA(证书权威机构)申请数字证书,来保证服务器的身份是可信的。
HTTP 1.0 /1.1/2.0/3.0 有什么区别?
| 对比项 | HTTP 1.0 | HTTP 1.1 | HTTP 2.0 | HTTP 3.0 |
|---|---|---|---|---|
| 底层协议 | TCP | TCP | TCP | UDP + QUIC |
| 连接方式 | 短连接 | 长连接(默认) | 多路复用长连接 | QUIC 连接 |
| 队头阻塞 | 严重 | 应用层阻塞 | TCP 层阻塞 | 彻底无阻塞 |
| 数据格式 | 纯文本 | 纯文本 | 二进制分帧 | 二进制 |
| 头部压缩 | 无 | 无 | HPACK | QPACK |
| 服务端推送 | 无 | 无 | 支持 | 支持 |
| 握手耗时 | 3 次握手 | 3 次握手 | TCP+TLS | 0-RTT / 1-RTT |
| 连接迁移 | 无 | 无 | 无 | 支持 |
| 安全性 | 明文 | 明文 | 需配合 TLS | 默认加密 |
QUIC(Quick UDP Internet Connections)是基于 UDP 的新一代传输层协议,是 HTTP/3 的底层核心,本质是把 TCP 的可靠性、TLS 的安全性、HTTP/2 的多路复用整合在 UDP 之上,解决 TCP 在现代网络(移动、弱网、高并发)的性能瓶颈。
HTTPS是如何防范中间人的攻击?
主要通过加密和身份校验机制来防范中间人攻击的:
-
加密:https 握手期间会通过非对称加密的方式来协商出对称加密密钥。
-
身份校验:服务器会向证书颁发机构申请数字证书,证书中包含了服务器的公钥和其他相关信息。
当客户端与服务器建立连接时,服务器会将证书发送给客户端。客户端会验证证书的合法性,包括检查证书的有效期、颁发机构的信任等。如果验证通过,客户端会使用证书中的公钥来加密通信数据,并将加密后的数据发送给服务器,然后由服务端用私钥解密。
中间人攻击的关键在于攻击者冒充服务器与客户端建立连接,并同时与服务器建立连接。
但由于攻击者无法获得服务器的私钥,因此无法正确解密客户端发送的加密数据。同时,客户端会在建立连接时验证服务器的证书,如果证书验证失败或存在问题,客户端会发出警告或中止连接。
Http,RPC,gRPC的区别
HTTP:应用层的 "通用通信协议"
-
本质 :HTTP 是「应用层协议」(TCP/IP 五层模型的应用层),定义了客户端和服务端之间数据传输的格式、规则、交互方式,是跨系统通信的 "通用语言"。
-
核心特征:
-
无状态:服务端不保存客户端的会话信息(每次请求都是独立的);
-
基于文本:默认用 JSON/XML/ 表单等文本格式传输数据(易读但解析开销大);
-
通用灵活:支持 GET/POST/PUT 等请求方法,适配几乎所有跨平台场景;
-
版本演进:HTTP/1.1(短连接、无多路复用)→ HTTP/2(长连接、多路复用、二进制帧)→ HTTP/3(基于 QUIC,无队头阻塞)。
-
- RPC:远程过程调用的 "设计思想 / 模式"
-
本质 :RPC(Remote Procedure Call)是「远程过程调用模式」,核心目标是让调用远程服务器的方法,像调用本地方法一样简单,屏蔽网络通信、数据序列化 / 反序列化的细节。
-
核心特征:
-
方法级调用:调用的是 "远程的某个方法(如
userService.getUser(1))",而非 "传输一段数据"; -
封装网络细节:开发者不用关心 "怎么建立连接、怎么传数据、怎么解析响应",框架自动处理;
-
协议无关:RPC 是 "思想",可基于任意底层协议实现(比如基于 TCP、HTTP/1.1、HTTP/2 都可以);
-
强耦合(相对):通常需要客户端和服务端约定好接口、数据结构(比如定义接口文件)。
-
- gRPC:基于 HTTP/2 + Protobuf 的 "高性能 RPC 框架"
-
本质 :gRPC 是 Google 开源的「RPC 框架」,是 RPC 思想的具体落地实现,核心是基于 HTTP/2 做传输层、Protobuf 做序列化层,解决了传统 RPC "性能差、跨语言难" 的问题。
-
核心特征:
-
基于 HTTP/2:天然支持长连接、多路复用(一个连接处理多个请求)、服务端推送、头部压缩;
-
二进制序列化:用 Protobuf(谷歌自研)序列化数据,比 JSON 小 3-5 倍,解析速度快 20-100 倍;
-
跨语言:通过 Protobuf 定义接口,可生成 Java/Go/Python/C++ 等几乎所有语言的代码;
-
支持流式调用:除了 "简单请求 - 响应",还支持服务端流式、客户端流式、双向流式调用;
-
如果客户端禁用了cookie,session还能用吗?
默认情况下禁用 Cookie 后,Session 是无法正常使用的,但可以通过URL重写与隐藏表单字段绕过这个问题。
URL重写:每当服务器响应需要保持状态的请求时,将Session ID附加到URL中作为参数。
隐藏表单字段:每当服务器响应需要保持状态的请求时,可以在HTML表单中隐藏一个字段用来存储Session ID。
URI 和 URL 的区别是什么?
URI(Uniform Resource Identifier) 是统⼀资源标志符,可以唯⼀标识⼀个资源。
URL(Uniform Resource Locator) 是统⼀资源定位符,可以提供该资源的路径。它是⼀种具体的 URI,即 URL 可以⽤来标识⼀个资源,⽽且还指明了如何 locate 这个资源。
正向代理与反向代理的区别
正向代理是代理客户端 的服务器:客户端想访问某个服务端,但不能 / 不想直接访问,于是把请求发给正向代理服务器,由代理服务器转发请求给服务端,再把响应返回给客户端。
反向代理是 代理服务端的服务器:客户端想访问某个服务,但不知道具体是哪个服务端处理,于是把请求发给反向代理服务器,由反向代理根据规则(如负载均衡)转发请求给后端的某个服务端,再把响应返回给客户端。
正向代理 vs 反向代理:核心对比
| 维度 | 正向代理 | 反向代理 |
|---|---|---|
| 代理对象 | 客户端 | 服务端 |
| 客户端感知 | 知道代理存在(需配置) | 不知道代理存在 |
| 服务端感知 | 不知道代理存在 | 知道代理存在 |
| 核心作用 | 帮助客户端访问不能直接访问的资源 | 帮助服务端分担压力、提供安全防护 |
| 典型应用 | VPN、翻墙、公司内网访问 | Nginx 负载均衡、CDN、API 网关 |
传输层
TCP 与 UDP 的区别
-
是否⾯向连接 : TCP 提供⾯向连接的服务,在传送数据之前必须先建⽴连接,数据传送结束后要释放连接。UDP 在传送数据之前不需要先建⽴连接。
-
是否是可靠传输:TCP 提供可靠的传输服务,TCP 在传递数据之前,会有三次握⼿来 建⽴连接,⽽且在数据传递时,有确认、窗⼝、重传、拥塞控制机制。通过 TCP 连接传输的数 据,⽆差错、不丢失、不重复、并且按序到达。 远地主机在收到 UDP 报⽂后,不需要给出任何确认,并且不保证数据不丢 失,不保证是否顺序到达。
-
是否有状态 :这个和上⾯的"是否可靠传输"相对应。TCP 传输是有状态的,这个有状态说的是 TCP 会去记录⾃⼰发送消息的状态 ⽐如消息是否发送了、是否被接收了等等。为此 ,TCP 需要 维持复杂的连接状态表。⽽ UDP 是⽆状态服务,简单来说就是不管发出去之后的事情了。
-
传输效率 :由于使⽤ TCP 进⾏传输的时候多了连接、确认、重传等机制,所以 TCP 的传输效 率要⽐ UDP 低很多。
-
传输形式 : TCP 是⾯向字节流的,UDP 是⾯向报⽂的。
-
⾸部开销 :TCP ⾸部开销(20 ~ 60 字节)⽐ UDP ⾸部开销(8 字节)要⼤。
-
是否提供⼴播或多播服务 :TCP 只⽀持点对点通信,UDP ⽀持⼀对⼀、⼀对多、多对⼀、多对 多
TCP三次握手过程
第一次握手
客户端向服务端发送 SYN 报文 ,携带自己的初始序列号 seq = x,客户端进入 SYN_SENT(同步已发送)状态。
第二次握手
服务端收到 SYN 后,回复 SYN + ACK 报文:
确认号 ack = x + 1(确认收到客户端的 SYN)
携带自己的初始序列号 seq = y
服务端进入 SYN_RCVD(同步已接收)状态。
第三次握手
客户端收到 SYN+ACK 后,回复 ACK 报文:
确认号 ack = y + 1
序列号 seq = x + 1
客户端和服务端同时进入 ESTABLISHED(已连接)状态,连接正式建立。
TCP四次挥手
四次挥手是断开 TCP 全双工连接 的过程,因为 TCP 是双向通信,双方要各自关闭自己的发送通道,所以需要 4 次。
这里以客户端主动关闭,服务端被动关闭为例
-
第一次挥手
客户端发送 FIN 报文 ,序列号
seq = x,请求关闭发送数据通道,进入FIN_WAIT1(终止等待 1)状态。 -
第二次挥手
服务端收到 FIN 后,回复 ACK 报文 ,确认号
ack = x+ 1,序列号seq = y,进入CLOSE_WAIT(关闭等待)状态。客户端收到 ACK 后进入
FIN_WAIT2(终止等待 2),此时客户端不能再发数据,但还能收数据。 -
第三次挥手
服务端把剩余数据发完后,向客户端发送 FIN 报文 ,序列号
seq = z,进入LAST_ACK(最后确认)状态。 -
第四次挥手
客户端收到 FIN 后,回复 ACK 报文 ,确认号
ack = z + 1,序列号seq = x + 1,进入TIME_WAIT(时间等待)状态。
-
服务端收到 ACK 后直接关闭连接;
-
客户端等待 2MSL 后关闭,确保最后一个 ACK 被对方收到。
为什么是三次握手,不是两次?
核心目的只有两个:
-
确保双方「发送能力、接收能力」全都正常
-
第一次握手:服务端确认「客户端能发、自己能收」
-
第二次握手:客户端确认「自己能发能收、服务端能发能收」
-
第三次握手:服务端确认「自己能发能收,客户端能发能收」只有三次,才能完成双向收发能力的全量确认。
-
-
防止「失效的连接请求」导致服务端浪费资源
如果是两次握手,客户端发出去的旧 SYN 报文延迟到达服务端,服务端直接建立连接,会白白占用服务端资源,而客户端根本不知道连接已建立。
三次握手每一步丢包会发生什么?
-
第一次握手(客户端 SYN 丢包)
客户端收不到服务端的回复,会超时重传 SYN 报文,直到收到应答。
-
第二次握手(服务端 SYN+ACK 丢包)
客户端收不到会重传 SYN;
服务端收不到第三次 ACK,也会超时重传 SYN+ACK。
-
第三次握手(客户端 ACK 丢包)
服务端收不到,会认为自己的 SYN+ACK 没送达,继续重传 SYN+ACK;
客户端此时已认为连接建立,会在收到重传后再次补发 ACK。
TIME_WAIT 状态是怎么来的?有什么用?
怎么来的
主动关闭连接的一方(通常是客户端),在第四次挥手发送完 ACK 后 ,会立刻进入 TIME_WAIT 状态,并且等待 2MSL 才真正关闭连接。
为什么必须存在(两个核心作用)
① 保证最后一个 ACK 能被对方收到
如果 ACK 丢了,服务端会重传 FIN,TIME_WAIT 期间客户端可以再次回复 ACK。
② 让本次连接的所有网络报文彻底消失
防止旧连接的残留数据包,干扰后续新建的相同端口连接
MSL = Maximum Segment Lifetime
报文最大生存时间:一个 TCP 报文在网络上最多能活多久,超过就被丢弃
什么情况会出现大量TIME_WAIT,怎么解决
1.服务端成为主动关闭连接的一方,那么由于服务端宕机/服务端重启等,服务端会断开大量客户端的连接,产生大量TIME_WAIT
2.客户端高频创建 / 关闭连接。如在测试环境下开发者频繁刷新页面或者生产环境网络波动导致ack一直不被接收
3.使用HTTP 短连接接口(比如图片上传 / 查询接口),且设置了 Connection: close(强制关闭长连接),那么会产生频繁的tcp的建立与关闭,主动关闭方会产生大量 TIME_WAIT。
4.TIME_WAIT 超时时间设置过长,也可能导致堆积大量TIME_WAIT
解决方案:
1.由客户端主动关闭连接,避免服务端堆积大量TIME_WAIT导致服务直接瘫痪
2.避免频繁重连:对同一客户端的频繁重连做限流或增加重连的时间间隔。
3.用长连接替代短连接,避免频繁的建立tcp连接
4.对于已经出现的大量TIME_WAIT,可以调整内核参数快速降低数量、避免端口耗尽
为什么不能把服务器发送的 ACK 和 FIN 合并起来,变成三次挥⼿?
TCP 是全双工通信,客户端和服务端各有一套独立的「发送通道」和「接收通道」,关闭时要双方分别关闭自己的发送通道,不能合并关闭。
具体过程:
-
第一次挥手 :主动关闭方发 FIN,关闭自己的发送通道。
-
第二次挥手:被动关闭方回 ACK,确认收到关闭请求。这时被动关闭方可能还有数据没发完,所以不能立刻关闭,只能先回复确认。
-
第三次挥手 :等被动关闭方数据发完了,再发 FIN,关闭它的发送通道。
-
第四次挥手:主动关闭方回 ACK,双方彻底断开。
之所以不能像三次握手那样合并,是因为:
握手时服务端可以把 SYN(同步)+ ACK(确认) 合并发送;
但挥手时,ACK(确认关闭) 和 FIN(自己关闭) 之间可能有数据要传输,无法合并,所以必须是四次。
TCP 如何保证传输的可靠性?
-
校验和
发送方对数据、首部计算校验和,接收方收到后重新校验,一旦发现数据出错就直接丢弃,保证数据传输无错误。
-
序列号
给每个传输的报文段按顺序分配唯一序列号,接收方根据序列号对数据按序重组 ,同时能识别重复报文并丢弃,保证不重复、按序到达。
-
确认应答机制(ACK)
接收方每收到一段正确的数据,就会向发送方返回确认应答(ACK),明确告诉发送方「哪些数据已收到」,这是可靠传输的基础。
-
超时重传
发送方发送数据后会启动超时计时器,若超时未收到 ACK ,就判定报文丢失,立即重传该数据 ,从机制上解决丢包问题。
-
连接可靠管理
通过三次握手建立连接 ,确认双方收发能力都正常;通过四次挥手断开连接,保证双方数据都传输完毕再关闭,从连接层面保证可靠。
-
流量控制
基于滑动窗口 实现,接收方会告诉发送方自己的缓冲区剩余大小,发送方按接收能力调整发送速度,防止接收方缓冲区溢出导致数据丢失
-
拥塞控制
通过慢启动、拥塞避免、快重传、快恢复 四个阶段,根据网络拥塞程度动态调整发送窗口,避免网络拥塞引发大量丢包,保证整体传输稳定可靠。
简单总结:TCP 靠校验和防错、序列号排序、ACK 确认、超时重传 解决基础可靠,再用连接管理、流量控制、拥塞控制保证传输全程稳定。
