引言
TCP(传输控制协议)是互联网的基石协议之一。它提供了面向连接、可靠、基于字节流的传输服务。与UDP的简单封装不同,TCP通过复杂的机制保证了数据在网络中传输的可靠性。
本文将从TCP的核心特性出发,深入讲解连接状态机、三次握手与四次挥手、TIME_WAIT状态的意义,以及拥塞控制算法等高级主题。
第一部分:TCP 协议核心特性
一、协议特点
| 特性 | 说明 |
|---|---|
| 面向连接 | 通信前必须建立连接(三次握手),结束后断开连接(四次挥手) |
| 可靠传输 | 通过确认应答、超时重传、去重、乱序重排保证可靠性 |
| 流式服务 | 数据以字节流形式传输,无固定边界 |
| 全双工通信 | 双方可同时发送和接收数据 |
二、可靠性实现机制
确认应答(ACK):接收方收到数据后发送确认信息,告知发送方数据已到达。
超时重传:发送方发送数据后启动定时器,若未收到确认则重发数据包。
// 超时重传示意 发送端: 发送 seq=1 → 启动定时器 接收端: 收到数据 → 发送 ACK=2 发送端: 收到 ACK → 取消定时器 // 如果 ACK 丢失 发送端: 发送 seq=1 → 启动定时器 接收端: 收到数据 → 发送 ACK=2 (丢失) 发送端: 定时器超时 → 重传 seq=1去重处理:通过报文序号识别并丢弃重复数据包。
乱序重排:根据序号重新排列到达顺序错乱的数据包。
三、滑动窗口机制
滑动窗口是TCP的流量控制机制,用于调节发送速率,防止接收方缓冲区溢出。
工作原理:
窗口内数据可一次性发送(无需等待单个确认)
收到确认后窗口沿数据流方向滑动
窗口大小决定允许发送的未确认数据量
四、TCP 与 UDP 协议对比
| 对比维度 | TCP | UDP |
|---|---|---|
| 连接性 | 面向连接(三次握手) | 无连接 |
| 可靠性 | 可靠(确认+重传) | 不可靠(尽最大努力) |
| 数据边界 | 流式(无边界) | 数据报(有边界) |
| 传输效率 | 较低 | 较高 |
| 适用场景 | 文件传输、网页访问 | 实时视频、DNS查询 |
选择依据:
需要数据完整性 → TCP(如文件下载)
容忍丢包、要求低延迟 → UDP(如视频通话)
第二部分:TCP 连接状态机
一、状态总览
TCP连接从创建到关闭会经历多个状态变化,监控连接状态对排查网络问题至关重要。
| 状态 | 说明 |
|---|---|
CLOSED | 假想的起始状态,实际代码中不可见 |
LISTEN | 服务器监听状态,等待客户端连接 |
SYN_SENT | 客户端发送SYN后进入的状态 |
SYN_RCVD | 服务器收到SYN后进入的状态 |
ESTABLISHED | 三次握手完成后进入的连接状态 |
FIN_WAIT_1 | 主动关闭方发送FIN后进入的状态 |
FIN_WAIT_2 | 收到ACK后进入的状态 |
CLOSE_WAIT | 被动关闭方收到FIN后进入的状态 |
LAST_ACK | 被动关闭方发送FIN后进入的状态 |
TIME_WAIT | 主动关闭方完成四次挥手后进入的状态 |
二、状态观察方法
# 查看TCP连接状态
netstat -natp# 输出示例
# Proto Recv-Q Send-Q Local Address Foreign Address State
# tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN
# tcp 0 0 192.168.1.146:6000 192.168.1.100:54321 ESTABLISHED
# tcp 0 0 192.168.1.146:6000 192.168.1.100:54322 TIME_WAIT
第三部分:TCP 三次握手
一、握手流程
详细说明:
| 步骤 | 方向 | 报文内容 | 状态变化 |
|---|---|---|---|
| 1 | 客户端 → 服务器 | SYN=1, seq=x | 客户端进入 SYN_SENT |
| 2 | 服务器 → 客户端 | SYN=1, ACK=1, seq=y, ack=x+1 | 服务器进入 SYN_RCVD |
| 3 | 客户端 → 服务器 | ACK=1, ack=y+1 | 双方进入 ESTABLISHED |
二、为什么不能是两次握手?
两次握手的缺陷:无法确认客户端存活状态。
// 攻击场景
客户端发送SYN → 立即退出
服务端回复SYN+ACK → 等待客户端ACK(永远不会到来)
服务端资源被占用,造成资源浪费
三次握手的必要性:第三次ACK确认双方状态同步,防止半开连接。
三、SYN Flood 攻击
攻击原理:攻击者发送大量伪造SYN包,占满服务器的未完成握手队列。
防御措施:
SYN Cookie 技术
识别异常IP进行限流
防火墙检测同一IP的异常SYN报文频率
第四部分:TCP 四次挥手
一、挥手流程
二、为什么是四次挥手?
TCP是全双工通信,双方需要独立关闭自己的发送通道:
| 次数 | 发送方 | 报文 | 含义 |
|---|---|---|---|
| 1 | 主动方 | FIN | 主动方不再发送数据 |
| 2 | 被动方 | ACK | 确认收到关闭请求 |
| 3 | 被动方 | FIN | 被动方不再发送数据 |
| 4 | 主动方 | ACK | 确认关闭,进入TIME_WAIT |
能否简化为三次?
当被动方收到FIN后立即关闭连接时,可将FIN与ACK合并发送
协议设计为四次是因为无法预知程序员何时调用
close(),需要保持ACK的即时性
三、TIME_WAIT 状态详解
持续时间:2MSL(Maximum Segment Lifetime),通常约2分钟。
出现场景:仅出现在主动关闭连接的一端。
存在原因:
| 原因 | 说明 |
|---|---|
| 可靠终止连接 | 确保最后一次ACK丢失时能处理重传的FIN报文。若直接关闭,对方重发FIN将收到RST响应导致错误 |
| 处理延迟报文 | 等待2MSL时间确保所有报文在网络中消失,防止旧连接的延迟报文被新连接误接收 |
实际影响:
端口处于被占用状态,无法立即重启相同端口的服务
可通过设置
SO_REUSEADDR套接字选项重用端口
// 解决 TIME_WAIT 导致的端口占用问题 int opt = 1; setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));第五部分:TCP 头部结构
TCP报文头部可同时携带序号和确认号字段,这是实现可靠传输的关键技术基础。
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 源端口(16位) | 目的端口(16位) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 序列号(32位) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 确认号(32位) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 数据偏移 | 保留 | 标志位 | 窗口大小(16位) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 校验和(16位) | 紧急指针(16位) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 选项(最多40字节) | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+关键标志位:
| 标志位 | 含义 |
|---|---|
| SYN | 同步序列号,用于建立连接 |
| ACK | 确认号有效 |
| FIN | 发送方已无数据,请求关闭连接 |
| RST | 重置连接 |
| PSH | 立即推送数据 |
第六部分:拥塞控制
一、核心目标
提高网络利用率,降低丢包率,保证网络资源对每条数据流的公平性。
二、四个核心机制
| 机制 | 作用 | 触发条件 |
|---|---|---|
| 慢启动 | 指数增长发送窗口,探测网络容量 | 连接建立或检测到丢包 |
| 拥塞避免 | 线性增长窗口,防止网络过载 | 窗口达到慢启动阈值 |
| 快速重传 | 立即重传丢失报文段 | 收到3个重复ACK |
| 快速恢复 | 温和降速,避免立即进入慢启动 | 快速重传后 |
三、慢启动机制
工作原理:初始cwnd=2-4SMSS,每RTT时间窗口大小翻倍。
发送轮次 拥塞窗口cwnd
1 1
2 2
3 4
4 8
5 16 ← 达到慢启动阈值,转为拥塞避免
类比说明:如同高速公路车流控制,逐步增加避免瞬间拥堵。
四、拥塞避免
达到慢启动阈值(ssthresh)后,采用加法增大策略:
每收到一个ACK,cwnd增加1/cwnd
每个RTT周期,cwnd增加1
五、快速重传与快速恢复
触发条件:收到3个重复ACK(表明有报文段丢失)。
快速重传:立即重传丢失报文段,不必等待超时计时器。
快速恢复:
将ssthresh设为当前cwnd的一半
cwnd设置为新的ssthresh(或ssthresh+3)
进入拥塞避免阶段
检测到丢包 │ ▼ ssthresh = cwnd ÷ 2 │ ▼ cwnd = ssthresh + 3(快速恢复) │ ▼ 进入拥塞避免阶段(线性增长)六、AIMD 原则
| 策略 | 说明 | 阶段 |
|---|---|---|
| 加法增大 | 拥塞避免阶段的线性增长 | 拥塞避免 |
| 乘法减小 | 拥塞发生时窗口减半 | 快速恢复 |
第七部分:HTTP 协议基础
一、HTTP 请求方法
| 方法 | 含义 | 安全性 | 幂等性 |
|---|---|---|---|
| GET | 请求获取资源 | 是 | 是 |
| POST | 提交数据 | 否 | 否 |
| HEAD | 仅获取头部信息 | 是 | 是 |
| PUT | 上传资源 | 否 | 是 |
| DELETE | 删除资源 | 否 | 是 |
| OPTIONS | 查看支持的请求方法 | 是 | 是 |
二、HTTP 状态码分类
| 分类 | 含义 | 典型状态码 |
|---|---|---|
| 1xx | 信息类 | 100 Continue |
| 2xx | 成功类 | 200 OK |
| 3xx | 重定向类 | 301 Moved, 302 Found, 304 Not Modified |
| 4xx | 客户端错误 | 400 Bad, 401 Unauthorized, 403 Forbidden, 404 Not Found |
| 5xx | 服务器错误 | 500 Internal, 503 Unavailable |
三、HTTP 通信流程
浏览器访问网页的过程: 1. DNS解析:将域名解析为IP地址 2. TCP三次握手:与服务器建立连接(默认端口80) 3. 发送HTTP请求:GET /index.html HTTP/1.1 4. 服务器响应:HTTP/1.1 200 OK 5. 浏览器渲染:呈现页面内容 6. TCP四次挥手:关闭连接(或保持持久连接)知识小结
| 知识点 | 核心内容 | 难度 |
|---|---|---|
| TCP协议特点 | 面向连接、可靠传输、流式服务 | ⭐⭐⭐⭐ |
| UDP协议特点 | 无连接、不可靠、数据包服务 | ⭐⭐ |
| 三次握手 | SYN→SYN+ACK→ACK | ⭐⭐⭐ |
| 四次挥手 | FIN→ACK→FIN→ACK | ⭐⭐⭐⭐ |
| TIME_WAIT | 主动关闭方状态,持续2MSL | ⭐⭐⭐⭐ |
| 滑动窗口 | 流量控制机制 | ⭐⭐⭐⭐ |
| 拥塞控制 | 慢启动→拥塞避免→快速重传→快速恢复 | ⭐⭐⭐⭐⭐ |
| HTTP基础 | GET/POST方法,状态码分类 | ⭐⭐ |
本文详细讲解了TCP协议的核心机制:
可靠性实现:确认应答、超时重传、去重、乱序重排
状态机:从LISTEN到ESTABLISHED,再到TIME_WAIT的完整状态转换
三次握手与四次挥手:连接建立与关闭的完整流程
TIME_WAIT状态:存在的两个原因及实际影响
拥塞控制:慢启动、拥塞避免、快速重传、快速恢复四大机制
这些知识点不仅是网络编程的基础,更是面试中的高频考点。理解TCP协议的底层工作原理,能够帮助你在实际开发中更好地排查网络问题、优化传输性能。