☰
网络分层的理解
2026/9/27 2:57:32 网站建设 项目流程

网络通信是一个很复杂的问题,所以把它拆成多层,每一层只负责解决一类问题。上层不用关心下层具体怎么实现,只需要使用下层提供的服务。

首先要有整个网络分层的认知:

┌─────────────────────────────┐ │ 应用层 Application │ │ HTTP / HTTPS / DNS / WebSocket│ │ │ │ 解决:我要传什么? │ └──────────────▲──────────────┘ │ ┌──────────────┴──────────────┐ │ 传输层 Transport │ │ TCP / UDP / QUIC │ │ │ │ 解决:怎么可靠/高效地传给 │ │ 对方的哪个进程? │ └──────────────▲──────────────┘ │ ┌──────────────┴──────────────┐ │ 网络层 Network │ │ IP / ICMP │ │ │ │ 解决:数据包怎么找到目标机器? │ └──────────────▲──────────────┘ │ ┌──────────────┴──────────────┐ │ 链路层 Link │ │ Ethernet / Wi-Fi │ │ │ │ 解决:数据怎么在当前网络中 │ │ 从一个设备传到另一个? │ └─────────────────────────────┘

为什么一定要分层:

假设写了一个Java Web服务,

@GetMapping("/user/1")publicUsergetUser(){...}

写的是HTTP,但是HTTP自己根本没有能力:

  • 找到服务器IP
  • 把数据从电脑传到服务器
  • 保证数据不丢
  • 判断数据属于哪个Java进程
  • 通过网线WiFI发送比特

上面的问题当成面试官来问你,自己能不能回答上来。

所以HTTP必须依赖下面的东西:

HTTP ↓ TCP ↓ IP ↓ Ethernet / Wi-Fi ↓ 网卡 ↓ 交换机 / 路由器 / Internet ↓ 服务器

应用层

应用层解决的是应用程序之间到底要交换什么信息,以及信息按照什么格式表达。

典型的就是HTTP, DNS, WebSocket, SMTP, FTP
例如浏览器访问“https://www.example.com/user/123”,HTTP可以表达为:

GET /user/123 HTTP/1.1 Host: www.example.com Authorization: Bearer xxx

这里解决的就是“我要想服务器请求/user/123”
服务器返回:

HTTP/1.1 200 OK Content-Type: application/json { "id": 123, "name": "Tom" }

HTTP规定了请求方法、URL、Header、Body、Status Code、ContentType、Cookie、Cache-Control

扩展:Cookie, Session, Token, JWT, 浏览器存储,HTTP请求,鉴权

Cookie是HTTP协议中的一种客户端状态携带机制
Token是一种身份凭证
浏览器的LocalStorage, SessionStorage是存储位置

**Cookie:**本质上是一小段,服务器要求浏览器保存,并在后续符合条件的HTTP请求中自动携带的数据

例如用户第一次登录:

浏览器 │ │ POST /login │ username=Tom&password=123 ↓ 服务器 │ │ 登录成功 │ │ Set-Cookie: sessionId=abc123 ↓ 浏览器

服务器的响应式:

HTTP/1.1 200 OK Set-Cookie: sessionId=abc123; HttpOnly; Secure

浏览器看到Set-Cookie,之后就会把sessionId=abc123保存起来,以后访问接口GET /users/profile,浏览器就会自动带Cookie: sessionId=abc123,

所以,Cookie是通过HTTP Header在客户端和服务器之间传递的。

LocalStorage:实际上Cookie, LocalStorage, SessionStorage,都是浏览器存储数据的机制,但行为不同。

  • Cookie浏览器保存,访问符合Domain/Path等条件的服务器时会自动带上,
  • LocalStorage,浏览器保存token,但是浏览器不会自动把LocalStorage里的token放到HTTP请求里,必须JavaScript主动拿出来,发送给服务器

另外注意Cookie有带来了CSRF问题,跨站请求伪造。所以Cookie鉴权经常需要SameSite, CSRF Token, Origin/ Referer校验。

鉴权:

  • Session鉴权
  • JWT

最传统的Cookie + Session。结合下面流程图理解:

登录 浏览器 ───── username/password ─────→ 服务端 │ ↓ 创建 Session │ ↓ sessionId=abc123 │ 浏览器 ←──── Set-Cookie ──────────────┘ 后续请求 浏览器 ── Cookie: sessionId=abc123 ──→ 服务端 │ ↓ Redis查询 │ ↓ userId=10001 │ ↓ 鉴权成功

这里cookie存的sessionId实际就是一个索引/凭证,所以Session鉴权属于有状态鉴权,服务器保存用户登录状态。

JWT是另一种思路:希望把一部分用户信息直接放进token中,由客户端携带,

浏览器 ↓ 用户名 + 密码 ↓ 服务器 ↓ 验证成功 ↓ 生成 JWT ↓ 返回 Token

浏览器保存tokoen,然后下次请求,请求中带上Authorization: Bearer token

拿到 JWT ↓ 验证签名 ↓ 验证 exp ↓ 读取 userId ↓ 鉴权成功

这里不一定需要Redis:token ->UserId,因此JWT常被用于无状态鉴权。

理解无状态:JWT把用户身份信息直接编码进了令牌本身,服务端拿到令牌就能自己验证并读出UserId,不需要再去redis里查一次映射关系。

而JWT方案,是userId直接写在token里,JWT, JSON Web Token,三段式结构Header.Payload.Signature,其中Payload是一段Json,经过Base64Url编码,里面可以直接放用户消息:

{"sub":"`10086","name":"张三","exp":1735689600}

服务端签发时,用密钥对Header.Payload做签名,得到Signature,最终token,

客户端下次请求带上它,服务端拿到后:

用密钥重新计算签名,和 token 里的 Signature 比对,验证没被篡改。

验证通过后,直接 Base64 解码 Payload,读出 sub 字段,也就是 UserId = 10086。

检查 exp 是否过期。

全程不需要查 Redis,因为 UserId 就在 token 里,签名保证了它不可伪造。

这正是JWT适合分布式、微服务、Serveless场景的原因,多个服务实例不需要共享redis就能独立鉴权。

另外注意JWT是token的一种格式,LocalStorage是浏览器保存数据的地方,

所以有这样的认知:

鉴权凭证 │ ┌────────────┴────────────┐ ↓ ↓ Session JWT │ │ │ │ sessionId Token │ ↓ Cookie

鉴权凭证的两种方式,然后存储是Cookie或者LocalStorage

整理的术语:

概念它是什么主要作用
HTTP应用层协议定义请求/响应
CookieHTTP 状态机制浏览器自动携带数据
LocalStorage浏览器存储保存前端数据
Session服务端会话状态保存用户登录状态
SessionId会话标识找到服务端 Session
Token身份凭证证明用户身份
JWTToken 的一种格式自包含身份信息 + 签名
Access Token访问凭证调用 API
Refresh Token刷新凭证获取新的 Access Token
Authentication认证证明“你是谁”
Authorization授权判断“你能干什么”
RBAC授权模型用户→角色→权限
HttpOnlyCookie 属性限制 JS 读取
SecureCookie 属性限制 HTTPS 传输
SameSiteCookie 属性控制跨站携带

传输层

传输层解决的就是端到端的进程通信

IP解决的是哪台机器,TCP解决的事这台机器上的哪个应用进程。例如:192.168.1.10:8080,这就是为什么Java Web服务监听8080

IP ↓ 找到机器 TCP Port ↓ 找到机器上的进程

HTTP给TCP的数据 ,TCP会通过可靠传输机制传输过去,而不是简单的将给的数据直接扔到网络上,这里可靠传输机制就不细讲了,之前已经理解过。

网络层

网络层负责把数据包从一个网络中的主机送到另一个网络中的主机。

这里面试官可能问,我浏览器是访问www.baidu.com,怎么送到百度服务器,IP层负责根据IP地址进行路由。

IP负责主机到主机的寻址和路由,TCP负责端到端的可靠传输以及进程间通信。例如:

192.168.1.10:54321 ↓ TCP ↓ 8.8.8.8:443

IP跨网络找到对应机器,然后TCP找到对应进程或服务进行连接传输

链路层

现在IP, TCP都对好了,这一跳到底怎么传。典型技术Ethernet, Wi-Fi,

IP是逻辑地址,MAC是链路层地址/网卡地址。当在当前局域网中真正发送数据时,需要知道当前下一跳设备的网卡地址。

例如:

电脑 192.168.1.10 ↓ 想访问 192.168.1.20

知道IP还需要知道1.20对应了哪个MAC,会涉及到ARP,实现IP和MAC的映射查询

真正发送一个HTTP请求时

以TCP/IP四层模型,

应用层:浏览器请求,得到HTTP Data
传输层,使用TCP,TCP添加自己的Header,

┌──────────────┐ │ TCP Header │ ├──────────────┤ │ HTTP Data │ └──────────────┘

里面包含了源端口、目标端口、序列号、确认号、窗口…,形成TCP Segment
IP层:TCP Segment交给IP,

┌──────────────┐ │ IP Header │ ├──────────────┤ │ TCP Header │ ├──────────────┤ │ HTTP Data │ └──────────────┘

IP Header中有源IP, 目标IP,TTL, 协议类型…
形成IP Packet,
链路层中IP Packet再交给Ethernet / Wifi,

┌────────────────┐ │ Ethernet Header│ ├────────────────┤ │ IP Header │ ├────────────────┤ │ TCP Header │ ├────────────────┤ │ HTTP Data │ └────────────────┘

这时候才变成当前链路可以发送的数据帧Ethernet Frame,然后经过:网卡 -》 网线/Wifi -》交换机/路由器 -》Internet

上述的过程就是封装Encapsulation,到了服务器:

Ethernet ↓ 去掉 Ethernet Header ↓ IP ↓ 去掉 IP Header ↓ TCP ↓ 去掉 TCP Header ↓ HTTP ↓ 交给 Web Server

就是解封装Decapsulation

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询