计算机网络
网络基础
TCP/IP模型
应用层:HTTP,规定请求和响应的格式,例如 GET /users/1。
传输层:TCP,通过端口区分应用的通信端点,并提供可靠、有序的字节流传输。
网络层:IP,提供地址,让路由器能把数据逐步转发到目标。
网络接口层:以太网、Wi-Fi 等,负责在当前链路上传输数据。
IP 和端口的区别
一台服务器上可能同时运行多个程序,比如 Java 后端、MySQL、Redis。请求到达服务器后,还要知道交给哪个程序。
| 标识 | 作用 | 例子 |
|---|---|---|
| IP 地址 | 定位目标主机的网络地址 | 192.168.1.10 |
| 端口号 | 区分主机上的通信端点 | Java 服务监听 8080,MySQL 监听 3306 |
应用层
HTTP 是什么?
HTTP 是一种应用层协议,规定浏览器和服务器之间,请求与响应应该怎么表达。
比如浏览器发送:
1 | GET /users/1 HTTP/1.1 |
这句话表达三个信息:
GET:我要获取资源。/users/1:我要获取编号为 1 的用户。HTTP/1.1:使用的协议版本。
服务器收到后,按照 HTTP 的规则回复状态码、响应头和用户数据。
HTTP 请求报文由什么组成?
以 HTTP/1.1 为例,一份请求包含:请求行、请求头、空行、可选的请求体。
1 | POST /users HTTP/1.1 |
① 请求行:要做什么
1 | POST /users HTTP/1.1 |
POST 是请求方法,/users 是请求目标,HTTP/1.1 是协议版本。这里表示向 /users 提交数据。
② 请求头:补充说明
1 | Host: example.com |
分别说明目标主机、请求体的数据格式,以及请求体的字节数。
③ 空行:分隔请求头和请求体
空行不是为了排版,它是报文结构的一部分。
④ 请求体:实际提交的数据
1 | {"name":"张三"} |
这里提交了一个名字。请求体不是每个请求都有,例如普通的 GET 查询通常没有请求体。
HTTP 响应报文由什么组成?
浏览器发出请求后,服务器可能这样回复:
1 | HTTP/1.1 200 OK |
它也分为四部分:状态行、响应头、空行、可选的响应体。
① 状态行:请求处理得怎么样
1 | HTTP/1.1 200 OK |
HTTP/1.1:协议版本。200:状态码,表示请求成功。OK:对状态码的简短说明。
② 响应头:描述这次响应
1 | Content-Type: application/json |
表示响应体采用 JSON 格式,长度是 9 字节。
③ 空行:分隔响应头和响应体
④ 响应体:实际返回的数据
1 | {"id":1} |
GET 和 POST
| 方法 | 主要语义 | 常见场景 |
|---|---|---|
| GET | 获取资源 | 查询用户、查看商品 |
| POST | 提交数据进行处理 | 创建用户、提交订单 |
GET 参数在 URL,POST 参数在请求体
POST 的数据放在请求体里,此时还不是加密状态
幂等是指同一个请求执行一次和多次,对服务端产生的预期效果相同。GET 具有幂等语义,POST 不保证幂等。
GET 具有安全语义,POST 不保证安全
HTTP 状态码
状态码第一位数字表示大类
| 分类 | 含义 | 例子 |
|---|---|---|
| 1xx | 提示信息,后续还有处理 | 100 |
| 2xx | 请求成功 | 200 |
| 3xx | 重定向或缓存验证等 | 301、304 |
| 4xx | 请求存在问题 | 404 |
| 5xx | 服务器处理出现问题 | 500 |
HTTPS
HTTPS:就是 HTTP 通过 TLS 加密传输。
主要解决三件事:防窃听、防篡改、验证服务器身份。
建立 HTTPS 连接时,先进行 TLS 握手,主流程记成:
- 协商参数:客户端和服务端协商 TLS 版本、密码算法等。
- 验证身份:服务端提供证书,客户端检查证书是否可信、域名是否匹配、是否过期等。
- 协商密钥:双方通过密钥交换机制,生成共享的会话密钥。
- 加密通信:使用会话密钥,通过对称加密保护 HTTP 数据。
DNS
把域名解析为 IP 地址
访问网站时,常见流程是:
- 先查浏览器、操作系统等本地缓存。
- 没有结果,就问配置的 DNS 递归解析器。
- 解析器没有缓存时,依次询问:根服务器 → 顶级域服务器 → 权威服务器。
- 得到 IP 后返回客户端,并按 TTL 缓存结果。
传输层
客户端服务端
客户端:主动请求服务的程序,比如电脑上的浏览器。
服务端:接收请求、提供服务的程序,比如部署在服务器上的 Java 后端。
在浏览器里打开一个网站,就是:
浏览器(客户端)发请求 → Java 后端(服务端)处理 → 把结果返回浏览器。
TCP 三次握手是在干嘛?
浏览器和 Java 后端准备通过 TCP 传数据时,要先建立连接。三次握手就是建立这个连接的过程,发生在发送普通 HTTP 请求之前。
TCP三次握手
TCP 建立连接时,要让双方确认通信能力,并同步双方的初始序列号。
假设客户端初始序列号是 x,服务端是 y:
SYN:我想建立连接;ACK:我确认收到了。
| 次数 | 方向 | 发送内容 |
|---|---|---|
| 第一次 | 客户端 → 服务端 | SYN,seq=x,请求建立连接 |
| 第二次 | 服务端 → 客户端 | SYN+ACK,seq=y,ack=x+1,确认客户端,同时发起自己的同步 |
| 第三次 | 客户端 → 服务端 | ACK,ack=y+1,确认服务端的同步 |
四次挥手
TCP 可以双向传数据,两个方向要分别关闭
FIN,表示发送方没有更多数据要发送。
假设浏览器先提出关闭:
| 次数 | 方向 | 意思 |
|---|---|---|
| 第一次 | 浏览器 → 服务端 | 我的数据发完了,之后不再发送 FIN |
| 第二次 | 服务端 → 浏览器 | 收到,但我可能还有数据要发给你ACK |
| 第三次 | 服务端 → 浏览器 | 我的数据也发完了,之后不再发送FIN |
| 第四次 | 浏览器 → 服务端 | 收到ACK |
为什么通常需要四次?
因为服务端收到浏览器的 FIN 时,可以先确认收到,但它可能还有数据没发送完。等发完后,才发送自己的 FIN,所以确认和关闭分成了两次。
TIME_WAIT
谁主动先发第一个 FIN(谁先调 close()),谁最后就会进入 TIME_WAIT。
原因:
最后一个 ACK 可能丢失
等一些旧数据消失
为什么等待 2MSL?
MSL 是报文在网络中的最大生存时间。等待 2MSL,可以覆盖报文一个来回的时间,并让旧报文过期。
CLOSE_WAIT
还是浏览器先关闭连接:
- 浏览器发送 FIN:“我不再发数据了。”
- 服务端回复 ACK:“收到了。”
- 服务端进入 CLOSE_WAIT,等待自己的应用程序关闭连接。
- 应用调用关闭操作后,服务端才会发送自己的 FIN。
所以,CLOSE_WAIT 就是在等本端应用关闭。
TCP 怎么保证可靠传输?
可靠性:把数据按顺序、无重复地交给对方应用;如果一直传不成功,最终会报错
如何保证:
① 序列号:给数据编号
TCP 按字节编号。假设发送了两段数据:
- 第一段:第 1~100 字节。
- 第二段:第 101~200 字节。
即使第二段先到,接收方也能根据编号整理顺序;收到重复内容,也能识别出来。
② ACK:告诉对方收到哪里了
如果前 100 字节都收到了,接收方可以回复:
接下来我要第 101 字节。
所以 ACK 的确认号表示“下一个期望收到的字节编号”。
③ 重传:没确认的数据再发
发送方迟迟收不到确认,会进行超时重传。TCP 也可以根据重复确认等信号,提前发现丢包并重传,不必一直等超时。
TCP 和 UDP 的区别
| TCP | UDP |
|---|---|
| 面向连接(需三次握手、四次挥手) | 无连接 |
| 提供可靠、有序的传输 | 不保证送达和顺序 |
| 面向字节流,没有消息边界 | 面向报文,保留消息边界 |
| 有流量控制、拥塞控制 | 协议本身没有这些机制 |
浏览器输入一个 HTTPS 地址后,发生了什么?
DNS 查地址:把域名解析成 IP。
TCP 建连接:通过三次握手建立连接。
TLS 做保护:验证服务器证书、协商密钥。
HTTP 传内容:浏览器发送请求,服务器处理并返回响应。
浏览器展示页面:解析 HTML、CSS,执行 JavaScript,可能继续请求图片等资源。
