一、TCP 通信阶段(面向连接)
1. 连接建立阶段(三次握手)
sequenceDiagramClient->>Server: SYN(seq=x)Server->>Client: SYN-ACK(seq=y, ack=x+1)Client->>Server: ACK(ack=y+1)
- 关键步骤:
- 客户端发送
SYN
(同步序列号)
- 服务端回应
SYN-ACK
(确认客户端序列号+1)
- 客户端发送最终
ACK
(确认服务端序列号+1)
- 状态变迁:
- 客户端:CLOSED → SYN_SENT → ESTABLISHED
- 服务端:LISTEN → SYN_RCVD → ESTABLISHED
2. 数据传输阶段
graph LRA[发送数据] --> B[等待ACK]B -->|超时未确认| AB -->|收到ACK| C[滑动窗口移动]
- 核心机制:
- 可靠传输:序列号确认(SEQ/ACK)
- 流量控制:窗口大小通告(Window Size)
- 拥塞控制:慢启动/快重传/快恢复
- 数据特征:
- 字节流传输(无明确报文边界)
- 支持全双工通信(双向数据流动)
3. 连接终止阶段(四次挥手)
sequenceDiagramClient->>Server: FIN(seq=u)Server->>Client: ACK(ack=u+1)Server->>Client: FIN(seq=v)Client->>Server: ACK(ack=v+1)
- 关键步骤:
- 主动关闭方发送
FIN
- 被动关闭方先回
ACK
,后发 FIN
- 最终双方确认关闭
- 状态变迁:
- 主动方:ESTABLISHED → FIN_WAIT_1 → FIN_WAIT_2 → TIME_WAIT → CLOSED
- 被动方:ESTABLISHED → CLOSE_WAIT → LAST_ACK → CLOSED
4. 特殊状态(TIME_WAIT)
- 持续时长:2*MSL(Maximum Segment Lifetime,默认60秒)
- 作用:
二、UDP 通信阶段(无连接)
1. 单阶段通信模型
graph TDA[发送数据报] --> B[接收数据报]B -->|可能丢失| C[无重传]B -->|可能乱序| D[应用层处理]
- 核心特征:
- 无需建立连接(直接发送)
- 无状态维护(服务端不记录客户端信息)
- 每个数据报独立处理
2. 伪连接实现(应用层)
三、协议阶段对比
对比项 |
TCP |
UDP |
连接建立 |
需要三次握手 |
无连接建立阶段 |
数据传输 |
可靠有序的字节流 |
不可靠无序的数据报 |
状态维护 |
维护连接状态(序列号、窗口等) |
无状态 |
连接终止 |
需要四次挥手 |
无终止过程 |
资源消耗 |
高(缓冲区、定时器等) |
低 |
典型延迟 |
高(握手/挥手开销) |
低 |
四、编程视角的关键差异
1. TCP 套接字API流程
graph TBServer[服务端] --> s1[socket()]s1 --> s2[bind()]s2 --> s3[listen()]s3 --> s4[accept()] --> s5[recv()/send()]s5 --> s6[close()]Client[客户端] --> c1[socket()]c1 --> c2[connect()]c2 --> c3[send()/recv()]c3 --> c4[close()]
2. UDP 套接字API流程
graph TBServer[服务端] --> s1[socket()]s1 --> s2[bind()]s2 --> s3[recvfrom()] --> s4[sendto()]Client[客户端] --> c1[socket()]c1 --> c2[sendto()] --> c3[recvfrom()]
五、典型问题分析
1. TCP 半关闭问题
- 场景:一方调用
shutdown(SHUT_WR)
后仍可接收数据
- 状态:进入
FIN_WAIT_1
→ FIN_WAIT_2
状态
- 编程注意:需正确处理
recv()
返回0的情况
2. UDP 粘包/丢包处理
- 解决方案:
- 添加应用层头部(包含长度字段)
- 实现超时重传机制
- 使用序列号标识数据报
- 示例协议:TFTP(简单文件传输协议)