Skip to content

这是我学习计算机网络时整理的笔记。作为后端,每天写接口调接口,但"数据从 A 到 B 到底经历了什么"值得系统过一遍——分层、三次握手、HTTP 报文是面试必问三件套。

一、解决什么问题:网络通信为什么分层

两台机器通信,要解决的问题层层叠叠:比特怎么在网线传输?数据怎么找到对方?丢了怎么办?传的内容怎么组织?

不分层:每个应用都要自己实现从网线到协议的每一层——灾难。 分层:每层只解决自己的问题,向上层提供"更友好的服务":

职责代表协议
应用层定义数据格式(HTTP 报文/JSON)HTTP、HTTPS、DNS
传输层端到端传输,保证可靠性TCP、UDP
网络层寻址和路由(怎么找到对方)IP、ICMP
链路层相邻设备间传比特帧以太网、WiFi

数据发送=逐层封装(每层加自己的头),接收=逐层解封

应用数据 [HTTP头+body]
  → 传输层 [TCP头 | HTTP数据]       ← 加端口、序号
  → 网络层 [IP头 | TCP | HTTP]      ← 加源/目标 IP
  → 链路层 [MAC帧头 | IP | ...]     ← 加 MAC 地址

二、TCP 三次握手:建立连接

TCP 是面向连接、可靠的协议——发数据前先建立连接,三次握手:

客户端                        服务端
  │ ① SYN(seq=x)  ────────►  │  SYN_SENT
  │ ② SYN+ACK(seq=y,ack=x+1) │  ← 收到,回复
  │ ◄────────────           │  SYN_RCVD
  │ ③ ACK(ack=y+1) ────────► │  连接建立 ESTABLISHED

为什么是三次,不是两次/四次?

  • 两次不够:客户端第一次 SYN 因网络滞留,超时重发,旧的 SYN 后到——服务端不知道是"旧请求",会建一条无效连接占资源。三次握手让客户端收到服务端 SYN 时确认双方都能收发(客户端能收、服务端能收),旧 SYN 对不上序号直接丢弃。
  • 四次多余:第三次 ACK 客户端已确认收发能力,服务端第三次已确认——双向能力验证在第三次就完成了。

一句话记忆:三次握手 = 双方互相确认"我能发你也能收"(SYN 表示"我要发",ACK 表示"我收到了")。

三、TCP 四次挥手:断开连接

客户端                           服务端
  │ ① FIN ──────────────►       │  FIN_WAIT_1
  │ ② ACK ◄────────────         │  CLOSE_WAIT(服务端还有数据要发)
  │ ③ FIN ◄────────────         │  LAST_ACK(服务端数据发完了)
  │ ④ ACK ──────────────►       │  TIME_WAIT → 关闭

为什么是四次:TCP 是全双工(两边可同时收发)——断开也要两边各自关。客户端 FIN 表示"我不发了"(①),服务端 ACK 表示"知道了,但我可能还有数据要发"(②),服务端发完再 FIN(③),客户端 ACK(④)。

TIME_WAIT 是什么:主动关闭方(客户端)等 2×MSL 才彻底关——确保最后一个 ACK 服务端能收到(丢了能重发),也确保旧连接报文在网络中消亡,不串到新连接。

四、HTTP:应用层协议(后端天天打交道)

请求报文

http
POST /api/user/login HTTP/1.1        ← 请求行:方法 路径 版本
Host: saas.cxeam.cn                   ← 请求头
Content-Type: application/json
Content-Length: 45

{"username":"admin","password":"***"} ← 请求体(GET 无 body)

响应报文

http
HTTP/1.1 200 OK                       ← 状态行:版本 状态码 短语
Content-Type: application/json
Content-Length: 120

{"code":0,"data":{...}}               ← 响应体

状态码(背这张表)

范围含义常见
1xx信息100 Continue
2xx成功200 OK、201 创建
3xx重定向301 永久、302 临时、304 未修改(缓存)
4xx客户端错误400 参数错、401 未认证、403 无权限、404 不存在
5xx服务端错误500 服务器异常、502 网关错、503 过载、504 超时

调试口诀:4xx 看自己(请求发错了),5xx 看服务器(后端出事了)。

五、实跑验证(curl 观察真实报文)

bash
# -v 显示完整 HTTP 报文
curl -v http://example.com/ 2>&1 | head -20

实测能看到

> GET / HTTP/1.1                    ← 请求行(客户端发的)
> Host: example.com                 ← 请求头
>
< HTTP/1.1 200 OK                   ← 状态行(服务端回的)
< Content-Type: text/html
<
<html>...                           ← 响应体

本机实测(对本地 dev server):

bash
curl -v http://localhost:5173/ 2>&1 | grep -E "^[<>] HTTP|^[<>] Content-Type" | head -6
# > GET / HTTP/1.1
# < HTTP/1.1 200 OK
# < Content-Type: text/html

小结

  • 四层模型:应用(HTTP)→ 传输(TCP)→ 网络(IP)→ 链路(以太网);发送封装、接收解封
  • 三次握手:SYN→SYN+ACK→ACK,确认双方收发能力;四次挥手:FIN→ACK→FIN→ACK,全双工各自关
  • HTTP:请求行/状态码/头/体;4xx 查自己、5xx 查服务器
  • 下一篇可以看《TCP 可靠传输与拥塞控制》(滑动窗口/重传/慢启动——为什么 TCP 可靠)和《HTTPS 握手》(TLS 加密)——整理中
  • 中间件视角:Redis/MQ 都走 TCP,见《Redis 快速入门》;接口联调排查见《线上调试

验证说明:HTTP 报文格式用 curl -v 实跑验证(请求行/状态行/头/体逐字段可见);三次握手/四次挥手为 TCP 协议标准(RFC 793/1122),静态核对。