一、TCP 是什么?
TCP(Transmission Control Protocol)= 传输控制协议
一句话:打电话模式------先接通,再说话,说完挂断。可靠、有序、不丢数据。
特点:
- 面向连接:通信前必须先建立连接(三次握手)
- 可靠传输:丢包重传、校验、排序
- 全双工:双方可以同时收发
- 面向字节流:数据是连续的字节流
- 有流量控制和拥塞控制
二、UDP 是什么?
UDP(User Datagram Protocol)= 用户数据报协议
一句话:发短信模式------写好就发,不管对方收没收到。快、但不保证可靠。
特点:
- 无连接:直接发送,不需要建立连接
- 不可靠:不保证送达、不保证顺序
- 面向数据报:一次发一个完整的包
- 头部开销小(8 字节 vs TCP 的 20 字节)
- 没有拥塞控制:网络再堵也照发不误
三、TCP vs UDP 对比
| 对比项 | TCP | UDP |
|---|---|---|
| 连接 | 面向连接 | 无连接 |
| 可靠性 | 可靠(重传、确认) | 不可靠 |
| 顺序 | 保证有序 | 不保证有序 |
| 速度 | 较慢 | 较快 |
| 头部大小 | 20 字节 | 8 字节 |
| 传输方式 | 字节流 | 数据报 |
| 适用场景 | 网页、文件传输、邮件 | 视频直播、游戏、DNS查询 |
四、三次握手(建立连接)
类比:你给朋友打电话
客户端 服务端
| |
| ① SYN=1, seq=x |
| "喂,你能听到吗?" ──────→ |
| |
| ② SYN=1, ACK=1, |
| seq=y, ack=x+1 |
| ←────── "听到了,你能听到我吗?"|
| |
| ③ ACK=1, seq=x+1, ack=y+1 |
| "能听到,咱们开始说吧" ──────→|
| |
| ✅ 连接建立,开始传数据 |
三次握手的目的:
- 确认双方的发送能力 和接收能力都正常
- 同步双方的初始序列号(seq)
- 防止已失效的连接请求到达服务器
面试题:为什么不能两次握手?
两次握手的问题:如果客户端发了一个连接请求在网络中延迟了,客户端超时后重新发了一个新请求并成功通信后断开。这时那个延迟的旧请求终于到达服务端,服务端以为是新请求就建立连接等待数据,但客户端根本不会发数据------服务端资源白白浪费。
三次握手就能避免这个问题:服务端收到旧请求回复后,客户端不会发第三次确认,连接就不会建立。
五、四次挥手(断开连接)
类比:打完电话挂断
客户端 服务端
| |
| ① FIN=1, seq=u |
| "我说完了" ──────→ |
| |
| ② ACK=1, ack=u+1 |
| ←────── "好的,我知道了" |
| |
| (服务端可能还有数据要发送...) |
| |
| ③ FIN=1, seq=w |
| ←────── "我也说完了" |
| |
| ④ ACK=1, ack=w+1 |
| "好的,拜拜" ──────→ |
| |
| ⏳ 客户端等待 2MSL 后关闭 |
| ✅ 连接彻底断开 |
面试题:为什么是四次而不是三次?
因为 TCP 是全双工的------双方都可以独立关闭自己的发送通道:
- 客户端说"我说完了"(FIN)→ 服务端确认"知道了"(ACK)
- 但服务端可能还没说完,需要继续发数据
- 等服务端也说完了 → 再发 FIN → 客户端确认 ACK
两个方向分别关闭,所以要 4 步。
面试题:为什么客户端要等 2MSL?
MSL(Maximum Segment Lifetime)= 报文最大生存时间。
等待 2MSL 的原因:
- 确保最后一个 ACK 能送达:如果服务端没收到最后的 ACK 会重发 FIN,等 2MSL 就能收到重发并再次 ACK
- 确保旧连接的残留数据包完全消失:避免影响后续新连接
六、TCP 可靠传输机制
| 机制 | 作用 |
|---|---|
| 序列号 | 保证数据有序,不乱序 |
| 确认应答(ACK) | 接收方告诉发送方"收到了" |
| 超时重传 | 发送后一段时间没收到 ACK,就重新发 |
| 滑动窗口 | 控制发送速率,不用一个包一个包等确认 |
| 流量控制 | 接收方告诉发送方"别发太快,我处理不过来" |
| 拥塞控制 | 网络堵了就放慢发送速度(慢启动→拥塞避免→快重传→快恢复) |