2. TCP协议基础:TCP头部结构、三次握手与四次挥手、状态转换图
TCP(Transmission Control Protocol,传输控制协议)是面向连接的、可靠的、基于字节流的传输层协议。在排查网络丢包与重传问题时,深入理解TCP的头部结构、连接建立与释放过程以及状态转换机制,是定位问题根源的基石。本节将系统梳理这些核心知识点。
2.1 TCP头部结构
TCP头部固定部分为20字节,其后可跟随选项字段。理解头部各字段对于分析抓包数据、判断异常行为至关重要。
排查要点: 在分析丢包时,重点关注序列号(Seq)、确认号(Ack)、窗口大小(Window)以及标志位(SYN、ACK、RST等)。
2.1.1 固定头部字段详解
| 字段 | 长度(位) | 作用与排查关联 |
|---|---|---|
| 源端口 / 目的端口 | 16 + 16 | 标识通信进程;端口号错误或冲突会导致连接失败。 |
| 序列号(Seq) | 32 | 用于数据排序与去重;重传时序列号不变,接收端通过序列号判断重复包。 |
| 确认号(Ack) | 32 | 期望收到的下一个序列号;Ack不增长或重复Ack是丢包与重传的关键信号。 |
| 数据偏移 | 4 | 指示头部长度;用于定位选项字段边界。 |
| 标志位 | 9 | SYN(建立连接)、ACK(确认)、FIN(释放连接)、RST(重置连接)、PSH(推送)、URG(紧急)。 |
| 窗口大小(Window) | 16 | 接收端通告的可用缓冲区大小;窗口为0表示接收端满,发送端停止发送,可能导致超时重传。 |
| 校验和 | 16 | 覆盖头部与数据;校验失败直接丢弃,是链路层丢包的原因之一。 |
| 紧急指针 | 16 | 仅在URG标志置位时有效,现代应用较少使用。 |
2.1.2 TCP头部结构SVG图
下图展示了TCP固定头部各字段的排列顺序与位宽,便于在抓包分析时快速定位字段位置。
2.2 三次握手:建立可靠连接
TCP通过三次握手在通信双方之间同步序列号,协商窗口大小与选项参数,确保连接建立前的双向可达性。
2.2.1 握手流程
- 第一次握手(SYN): 客户端发送SYN报文,序列号随机生成(如Seq=x),客户端进入
SYN_SENT状态。 - 第二次握手(SYN+ACK): 服务端收到后,回复SYN+ACK报文,确认号Ack=x+1,并携带自己的序列号Seq=y,服务端进入
SYN_RCVD状态。 - 第三次握手(ACK): 客户端收到后,发送ACK报文,确认号Ack=y+1,序列号Seq=x+1。双方进入
ESTABLISHED状态,连接建立。
排查提示: 如果抓包中只看到SYN报文而没有对应的SYN+ACK,说明服务端未响应,可能原因包括防火墙拦截、服务端口未监听、半连接队列满等。如果SYN+ACK发出后未收到ACK,则可能是客户端丢弃了SYN+ACK或网络单向丢包。
2.2.2 三次握手SVG流程图
2.3 四次挥手:优雅释放连接
TCP连接是全双工的,因此释放连接时需要双方各自关闭自己的数据通道,通常需要四次报文交换。
2.3.1 挥手流程
- 第一次挥手(FIN): 主动关闭方(如客户端)发送FIN报文,序列号为Seq=u,进入
FIN_WAIT_1状态。 - 第二次挥手(ACK): 被动关闭方(如服务端)收到后,回复ACK报文,确认号Ack=u+1,进入
CLOSE_WAIT状态。主动方收到后进入FIN_WAIT_2状态。 - 第三次挥手(FIN): 被动关闭方在数据发送完毕后,发送FIN报文,序列号为Seq=v,进入
LAST_ACK状态。 - 第四次挥手(ACK): 主动关闭方收到后,回复ACK报文,确认号Ack=v+1,进入
TIME_WAIT状态,等待2MSL后关闭。
常见问题: 大量
TIME_WAIT连接会占用系统资源,可能导致端口耗尽或连接建立失败。在排查高并发服务时,需关注netstat或ss命令中TIME_WAIT的数量。
2.3.2 四次挥手SVG流程图
2.4 TCP状态转换图
TCP连接在生命周期中会经历多个状态,理解状态转换是排查连接异常的基础。以下状态转换图涵盖了客户端与服务端的主要状态路径。
2.4.1 状态转换SVG图
2.4.2 关键状态说明
| 状态 | 含义 | 排查关注点 |
|---|---|---|
| LISTEN | 服务端等待客户端连接 | 端口是否监听;半连接队列是否溢出 |
| SYN_SENT | 客户端已发送SYN,等待SYN+ACK | 若长时间停留,可能网络不可达或服务端未响应 |
| SYN_RCVD | 服务端已收到SYN,等待ACK | 若大量堆积,可能遭受SYN Flood攻击 |
| ESTABLISHED | 连接已建立,正常数据传输 | 关注连接数是否达到上限 |
| FIN_WAIT_1 / FIN_WAIT_2 | 主动关闭方等待对方确认/关闭 | 若大量FIN_WAIT_2,可能对方未关闭连接 |
| CLOSE_WAIT | 被动关闭方等待应用程序关闭 | 若大量CLOSE_WAIT,通常为应用程序未正确关闭socket |
| TIME_WAIT | 等待2MSL确保所有报文消失 | 高并发短连接场景下数量可能很大,需调整内核参数 |
排查命令速查:
netstat -antp | grep ESTABLISHED — 查看当前连接数ss -ant state time-wait — 查看TIME_WAIT连接netstat -s | grep -i "listen" — 查看半连接队列溢出统计
2.5 本章小结
- TCP头部中的序列号、确认号、窗口大小和标志位是丢包与重传排查的核心字段。
- 三次握手确保连接建立前的双向可达性与序列号同步;握手失败通常指向网络或服务端问题。
- 四次挥手释放全双工连接;
TIME_WAIT与CLOSE_WAIT是生产环境中常见的异常状态。 - 状态转换图提供了连接生命周期的全局视图,是分析连接异常的基础工具。