跳到主要内容

TCP/IP协议栈详解

TCP/IP协议栈是互联网的基础,定义了数据在网络中传输的标准。理解TCP/IP协议对于网络编程和系统设计至关重要。

核心价值

TCP/IP = 可靠传输 + 端到端通信 + 分层架构 + 全球互联

  • 🌐 分层设计:应用层、传输层、网络层、链路层清晰分工
  • 🔒 可靠传输:TCP提供面向连接的可靠数据传输
  • 高效通信:UDP提供无连接的高效数据传输
  • 🎯 端到端:从源主机到目标主机的完整通信路径
  • 🔄 自适应:流量控制和拥塞控制保证网络稳定

1. 网络模型对比

1.1 OSI七层模型 vs TCP/IP四层模型

层次名称功能协议示例设备示例
第7层应用层为应用程序提供网络服务HTTP、FTP、SMTP、DNS网关、代理服务器
第6层表示层数据格式转换、加密解密SSL/TLS、JPEG、MPEG加密设备
第5层会话层建立、管理、终止会话NetBIOS、RPC、SQL会话管理器
第4层传输层端到端可靠数据传输TCP、UDP网关
第3层网络层路由选择和逻辑寻址IP、ICMP、ARP路由器
第2层数据链路层帧同步、错误检测Ethernet、PPP、WiFi交换机、网桥
第1层物理层比特流传输电缆、光纤、无线集线器、中继器

1.2 协议栈数据封装过程

2. TCP协议详解

2.1 TCP协议特性

TCP(Transmission Control Protocol)是面向连接的可靠传输协议,提供以下特性:

TCP核心特性
  • 面向连接:通信前需要建立连接
  • 可靠传输:保证数据完整性和顺序
  • 流量控制:防止发送方发送过快
  • 拥塞控制:防止网络拥塞
  • 全双工通信:双向同时传输数据
  • 字节流服务:面向字节流而非报文

2.2 TCP三次握手

TCP连接建立需要三次握手,确保双方都能收发数据。

第一次握手(SYN)

  • 客户端发送SYN包(SYN=1),选择初始序列号seq=x
  • 客户端进入SYN_SENT状态
  • 表示客户端请求建立连接

第二次握手(SYN+ACK)

  • 服务器收到SYN包,发送SYN+ACK包
  • SYN=1表示同意建立连接,选择初始序列号seq=y
  • ACK=1表示确认,ack=x+1确认收到客户端的SYN
  • 服务器进入SYN_RCVD状态

第三次握手(ACK)

  • 客户端收到SYN+ACK包,发送ACK包确认
  • ACK=1,ack=y+1确认收到服务器的SYN
  • 客户端进入ESTABLISHED状态
  • 服务器收到ACK后也进入ESTABLISHED状态

2.3 TCP四次挥手

TCP连接断开需要四次挥手,因为TCP是全双工通信。

第一次挥手(FIN)

  • 客户端发送FIN包,表示不再发送数据
  • 客户端进入FIN_WAIT_1状态
  • 但仍可以接收数据

第二次挥手(ACK)

  • 服务器收到FIN包,发送ACK确认
  • 服务器进入CLOSE_WAIT状态
  • 客户端收到ACK后进入FIN_WAIT_2状态

第三次挥手(FIN)

  • 服务器发送完剩余数据后,发送FIN包
  • 服务器进入LAST_ACK状态
  • 客户端收到FIN后进入TIME_WAIT状态

第四次挥手(ACK)

  • 客户端发送ACK确认服务器的FIN
  • 服务器收到ACK后进入CLOSED状态
  • 客户端等待2MSL后进入CLOSED状态

2.4 TCP状态转换图

3. TCP流量控制与拥塞控制

3.1 滑动窗口机制

TCP使用滑动窗口实现流量控制,防止发送方发送过快导致接收方缓冲区溢出。

发送窗口

  • 已发送已确认:已经发送并收到ACK的数据
  • 已发送未确认:已发送但未收到ACK的数据
  • 可发送:可以发送的数据(受窗口大小限制)
  • 不可发送:超出窗口大小,暂时不能发送

接收窗口

  • 已接收:已经接收并发送ACK的数据
  • 可接收:可以接收的数据范围
  • 不可接收:超出接收缓冲区的数据

窗口大小调整

c
1// TCP头部窗口字段(16位)
2struct tcphdr {
3 uint16_t window; // 窗口大小(字节)
4 // ... 其他字段
5};
6
7// 实际窗口大小 = window << window_scale
8// window_scale在TCP选项中协商(0-14)

3.2 拥塞控制算法

TCP拥塞控制防止网络拥塞,包括慢启动、拥塞避免、快重传、快恢复四个阶段。

慢启动算法

  • 初始拥塞窗口cwnd = 1 MSS
  • 每收到一个ACK,cwnd += 1
  • 指数增长:1 → 2 → 4 → 8 → 16...
python
1# 慢启动伪代码
2def slow_start():
3 cwnd = 1 # 初始拥塞窗口
4 ssthresh = 65535 # 慢启动阈值
5
6 while cwnd < ssthresh:
7 send_data(cwnd) # 发送cwnd个MSS
8 ack_count = wait_for_acks()
9 cwnd += ack_count # 每个ACK增加1
10
11 if timeout_occurred():
12 ssthresh = cwnd // 2
13 cwnd = 1
14 break

慢启动阈值(ssthresh)

  • 初始值通常为65535字节
  • 发生拥塞时:ssthresh = cwnd / 2
  • cwnd >= ssthresh时进入拥塞避免

4. UDP协议详解

4.1 UDP协议特性

UDP(User Datagram Protocol)是无连接的传输协议,提供简单高效的数据传输。

markdown
1| 特性 | TCP | UDP | 适用场景 |
2|------|-----|-----|----------|
3| 连接性 | 面向连接 | 无连接 | TCP适合可靠传输,UDP适合实时传输 |
4| 可靠性 | 可靠传输 | 不可靠传输 | TCP保证数据完整性,UDP需要应用层处理 |
5| 速度 | 较慢 | 快速 | UDP延迟更低,适合实时应用 |
6| 头部开销 | 20-60字节 | 8字节 | UDP开销更小,效率更高 |
7| 流量控制 | 支持 | 不支持 | TCP防止接收方过载 |
8| 拥塞控制 | 支持 | 不支持 | TCP适应网络状况 |
9| 数据边界 | 字节流 | 数据报 | UDP保持消息边界 |
10| 多播支持 | 不支持 | 支持 | UDP支持一对多通信 |

4.2 UDP应用场景

视频直播

java
1// UDP视频流发送示例
2public class VideoStreamer {
3 private DatagramSocket socket;
4
5 public void streamVideo(byte[] videoData, InetAddress clientAddr, int port) {
6 try {
7 // 分片发送视频数据
8 int chunkSize = 1400; // 避免IP分片
9 for (int i = 0; i < videoData.length; i += chunkSize) {
10 int length = Math.min(chunkSize, videoData.length - i);
11 byte[] chunk = Arrays.copyOfRange(videoData, i, i + length);
12
13 DatagramPacket packet = new DatagramPacket(
14 chunk, length, clientAddr, port);
15 socket.send(packet);
16 }
17 } catch (IOException e) {
18 // 处理异常,但不重传
19 logger.warn("Video packet lost: " + e.getMessage());
20 }
21 }
22}

在线游戏

  • 玩家位置更新
  • 游戏状态同步
  • 实时交互数据

5. 常见面试问题

5.1 基础概念问题

Q1: 为什么TCP需要三次握手,而不是两次或四次?

A: 三次握手的目的是确认双方的收发能力:

  • 第一次握手:确认客户端发送能力、服务器接收能力
  • 第二次握手:确认服务器发送能力、客户端接收能力
  • 第三次握手:确认客户端接收能力

两次握手无法确认客户端接收能力,四次握手则是多余的。

Q2: TIME_WAIT状态的作用是什么?

A: TIME_WAIT状态有两个作用:

  1. 确保最后的ACK能够到达对方
  2. 等待网络中延迟的数据包消失,避免影响新连接

Q3: TCP如何保证可靠传输?

A: TCP通过以下机制保证可靠传输:

  • 序列号和确认号
  • 超时重传机制
  • 流量控制(滑动窗口)
  • 拥塞控制
  • 校验和验证

5.2 实际应用问题

网络编程最佳实践

  1. 选择合适的协议

    • 可靠性要求高:选择TCP
    • 实时性要求高:选择UDP
    • 考虑网络环境和应用特点
  2. 处理网络异常

    • 设置合理的超时时间
    • 实现重连机制
    • 优雅处理连接断开
  3. 性能优化

    • 使用连接池
    • 批量处理数据
    • 异步非阻塞IO
    • 合理设置缓冲区大小

通过深入理解TCP/IP协议栈,你将能够:

  • 设计高效的网络通信方案
  • 解决网络编程中的常见问题
  • 优化网络应用的性能
  • 处理复杂的网络环境挑战

评论