菜鸟-创作你的创作

【Linux网络】Linux 网络编程:传输层TCP(二)

Linux 网络编程:传输层 TCP(二)—— TCP 可靠传输机制详解

在上一篇《Linux 网络编程:传输层 TCP(一)》中,我们介绍了 TCP 的基本概念、三次握手与四次挥手。本篇将深入讲解 TCP 的核心——可靠传输机制,包括确认应答、序列号、重传机制、滑动窗口、流量控制和拥塞控制等内容。


一、TCP 为什么可靠?

TCP(Transmission Control Protocol)是面向连接、可靠传输的协议。

相比 UDP:

特性TCPUDP
是否连接
是否可靠
数据顺序保证不保证
流量控制支持不支持
拥塞控制支持不支持

TCP 能够保证:


二、序列号(Sequence Number)

TCP 发送数据时,会给每个字节编号。

例如:

客户端发送:

Hello TCP

转换为字节:

H e l l o   T C P
1 2 3 4 5 6 7 8 9

TCP 会维护一个序列号:

Seq = 1000

发送:

Seq=1000
Length=9

表示:

1000~1008

这些字节的数据已经发送。


序列号作用

用于:

1. 数据排序

假设:

包1 Seq=1000
包2 Seq=2000
包3 Seq=3000

网络中:

包2先到
包1后到
包3最后到

TCP 根据序列号重新排序:

1000
2000
3000

应用层看到的数据仍然正确。


2. 检测丢包

例如:

1000
2000
4000

发现:

3000 丢失

TCP 自动请求重传。


三、确认应答机制(ACK)

TCP 每收到数据:

都会发送确认报文。

例如:

客户端 → 服务端

Seq=1000
Length=100

服务端收到后:

ACK=1100

表示:

1000~1099
已经收到

下一次请从:

1100

开始发送。


ACK 的意义

确认:

我已经收到你发送的数据

避免:

发送方不知道数据是否成功到达


四、超时重传机制

如果发送方迟迟收不到 ACK:

Seq=1000

发送后:

ACK未返回

TCP 认为:

数据丢失

于是:

重新发送

这就是:

Retransmission

重传机制。


超时时间(RTO)

TCP 不会立刻重传。

而是等待:

RTO
Retransmission Timeout

例如:

200ms

超过:

200ms

还没 ACK:

重传


动态调整

网络快:

RTO变小

网络慢:

RTO变大

Linux 内核自动计算:

RTT
Round Trip Time

动态调整超时时间。


五、快速重传(Fast Retransmit)

传统重传:

等超时

效率较低。

TCP 增加:

快速重传


例如:

1000
2000
3000
4000

其中:

2000丢失

收到:

1000
3000
4000

接收方持续发送:

ACK=2000
ACK=2000
ACK=2000

连续三个重复 ACK:

Duplicate ACK

发送方立即判断:

2000丢失

无需等待超时:

直接重传

提高效率。


六、滑动窗口机制(Sliding Window)

如果:

发一个包
等ACK
再发一个包

效率极低。

TCP 引入:

滑动窗口


工作原理

例如窗口大小:

5000字节

发送方可连续发送:

1000
2000
3000
4000
5000

无需等待 ACK。


接收:

ACK=3000

表示:

前3000字节收到

窗口向前滑动:

3001~8000

继续发送。


窗口示意图

已确认 | 已发送未确认 | 可发送 | 不可发送

--------|-----------|------|-------

随着 ACK 到来:

窗口不断向前移动

因此称为:

Sliding Window


七、流量控制(Flow Control)

问题:

发送方速度快。

接收方速度慢。

例如:

发送:
100MB/s

接收:
10MB/s

接收缓冲区很快满了。


TCP 解决方案

接收方告诉发送方:

Window = 4096

表示:

还能接收4096字节

发送方最多发送:

4096字节


缓冲区满

接收方:

Window = 0

表示:

别发了

发送方暂停。


缓冲区恢复

接收方:

Window = 2048

发送方继续发送。


八、拥塞控制(Congestion Control)

流量控制:

防止接收方崩溃

拥塞控制:

防止网络崩溃


网络拥塞

例如:

100台主机

同时发送:

10Gbps

交换机:

只有1Gbps

结果:

大量丢包

网络拥塞。


九、慢启动(Slow Start)

TCP 不知道网络能力。

开始时:

小流量发送

拥塞窗口:

cwnd = 1 MSS

例如:

1460字节


每收到 ACK:

窗口翻倍:

1
2
4
8
16
32
64

指数增长。


示意图

时间 →

1
2
4
8
16
32
64

快速探测网络带宽。


十、拥塞避免(Congestion Avoidance)

达到阈值:

ssthresh

后:

不再指数增长。

改为:

线性增长

例如:

64
65
66
67
68

避免网络突然拥塞。


十一、TCP 拥塞控制过程

完整流程:

慢启动
   ↓
达到阈值
   ↓
拥塞避免
   ↓
发现丢包
   ↓
快速重传
   ↓
快速恢复
   ↓
继续拥塞避免

现代 Linux 默认使用:

作为拥塞控制算法。


十二、TCP 发送与接收缓冲区

Linux Socket 内部:

应用程序
    ↓
发送缓冲区
    ↓
TCP
    ↓
网络

接收端:

网络
    ↓
TCP
    ↓
接收缓冲区
    ↓
应用程序


查看缓冲区:

sysctl -a | grep tcp

或:

cat /proc/sys/net/ipv4/tcp_rmem
cat /proc/sys/net/ipv4/tcp_wmem

示例:

4096 87380 6291456

表示:

最小值
默认值
最大值


十三、Linux 中 TCP 状态查看

查看连接:

ss -ant

或者:

netstat -ant

结果:

ESTAB
LISTEN
TIME_WAIT
CLOSE_WAIT


查看 TCP 统计:

ss -s

输出:

TCP:
estab 15
closed 200
timewait 20


十四、面试高频问题

TCP 为什么可靠?

答:


TCP 为什么比 UDP 慢?

因为 TCP 需要:

额外开销较大。


滑动窗口有什么作用?

提高吞吐量。

允许:

连续发送多个数据包

而不必等待每个 ACK。


流量控制与拥塞控制区别?

流量控制:

发送方 ↔ 接收方

关注:

接收能力

拥塞控制:

发送方 ↔ 网络

关注:

网络承载能力


总结

TCP 之所以能够成为互联网最重要的传输协议,核心原因在于其完善的可靠传输机制:

  1. 序列号保证数据有序。
  2. ACK 保证数据已收到。
  3. 超时重传解决丢包问题。
  4. 快速重传减少等待时间。
  5. 滑动窗口提高传输效率。
  6. 流量控制保护接收端。
  7. 拥塞控制保护整个网络。

理解这些机制后,再学习 Linux Socket 编程中的 send()recv()epoll()、高并发服务器设计时,会更容易理解 TCP 在内核中的工作原理。

退出移动版