理解TCP如何稳定、高效地 工作在网络上的关键

发布于:2025-07-16 ⋅ 阅读:(16) ⋅ 点赞:(0)


前言

TCP,最近手里项目又重新涉及到了关于以太网的通信,但对其的了解已经过去了好几年,所以,今天博主将对其重新回忆回忆,尽可能地将比较深入的知识点提取起来。因为在之前的文章中是有详细讲解过关于TCP的三次握手、四次挥手以及相关的报文分析和工具。感兴趣的朋友可以参考下历史文章:

1、OSI七层模型和TCP/IP四层模型介绍

2、OSI七层模型和TCP/IP四层模型形象实例

3、TCP协议工作原理详细介绍(形象举例版)

4、TCP协议工作原理详细介绍(具体参数版)

一、TCP的拥塞控制算法

拥塞控制是TCP最核心、最复杂的部分之一,目的是防止发送方过多地发送数据,导致网络链路(路由器、交换机)缓冲区溢出,进而引发丢包和延迟增加。TCP通过一系列算法动态调整发送速率。

1.1、核心思想

1.1.1、慢启动(SlowStart)

连接建立初期或超时重传后,发送方以较低的速率开始,然后指数级地增加发送速率(通常每次成功收到Ack,拥塞窗口cwnd增加1个MSS),直到达到一个阈值(慢启动阈值ssthresh)或检测到丢包。

1.1.2、拥塞避免(Congestion Avoidance)

当cwdd超过ssthresh后,进入拥塞避免阶段。此时,发送速率不再指数增长,而是线性增长(通常每收到一个完整的窗口的ACK,cwdd增加1/cwdd个MSS)。这更加保守地探测网络容量。

1.1.3、快速重传(FastRetransmit)&快速恢复(FastRecovery)

当发送方收到连续三个重复的ACK(表明接收方收到了一个失序的数据包),它认为网络可能发生了轻微拥塞(丢了一包,但后续包已到达接收方)。此时,不等待RTO超时,立即重传丢失的那个包(快速重传)。这快速恢复阶段会适度降低cwdd(通常设为ssthresh的值或ssthresh + 3*dupACK),并进入拥塞避免阶段,而不是回到慢启动。这比超时重传更高效。

1.2、主要算法演变

1.2.1、Reno

经典算法,包含慢启动、拥塞避免、快速重传、快速恢复。快速恢复后回到拥塞避免。

1.2.2、NewReno

对Reno的改进,处理多个包丢失的情况更加有效。在快速恢复阶段,如果仍收到重复ACK,会继续重传。

1.2.3、Cubic

由腾讯提出,是目前互联网上非常主流的算法。它假设网络带宽随时间变化呈立方关系,试图在网络拥塞时快速恢复带宽,并在高带宽长延迟网络下表现更好。

1.2.4、BBR

由Google提出,思路与前述基于丢包的算法不同。BRR试图直接测量带宽和瓶颈带宽处的往返延时,并据此调整发送速率,避免缓冲区填充,旨在最大化利用可用带宽同时最小化延迟。它在高带宽丢包网络中的表现优异。

1.3、挑战

不同TCP实现可能使用不同的拥塞控制算法,这可能导致“不公平性”(某些连接占用过多的带宽)。此外,现代网络环境(WIFI、移动网络)的动态性也给拥塞控制带来了新的挑战。

二、TCP选项字段

TCP头部有一个选项字段,长度可变,最多40个字节(因为TCP头部固定20字节,总长度为20字节+选项)。这个字段用于协商和传递各种额外的控制信息。

2.1、常见的TCP选项

2.1.1、MSS (Maximum Segment Size)

最大分段大小。在三次握手时交换,告知对方自己能够接收的最大TCP分段数据量(不包括TCP头部和IP头部)。这有助于避免IP分片,提高效率。通常受MTU(链路最大传输单元)限制,减去IP和TCP头部长度。

2.1.2、Window Scale(窗口缩放)

由于TCP头部窗口字段只有16位,最大只能表示65535字节。对于高带宽长延迟网络,这个窗口太小。窗口缩放选项允许双方协商一个移位因子,将实际的窗口大小左移该因子位,从而支持更大的窗口(可达1GB).

2.1.3、Timestamps(时间戳)

包含两个字段:发送方的时间戳值和回显的时间戳回显请求。主要用于计算RTT(往返时间)的更精确估计,以及帮助处理包失序和重复包。在快速重传和快速恢复中也有用。

2.1.4、SACK(Selective Acknowledgment)

选择性确认。允许接收方通知发送方哪些数据块已经成功接收,而不是只能确认最后一个连续接收到的字节。这大大提高了在乱序和丢包情况下的传输速率,因为发送方可以只重传丢失的包,而不是重传丢失包之后的所有包。

2.1.5、NOP(No-Operation)

无操作。通常用于填充或对齐选项字段,使其长度为4字节的倍数。

2.2、作用

这些选项极大地增强了TCP的功能和适应性,使其能够更高地应对不同的网络环境和应用需求。

三、TCP异常处理

TCP虽然设计为可靠的协议,但在复杂的网络环境中,各种异常情况仍会频繁发生。TCP需要优雅地处理这些异常,以保证连续的稳定性和数据的最终可靠传输。

3.1、常见的异常及处理

3.1.1、丢包

3.1.1.1、发送方丢包
发送方超时(没有收到ACK)或收到重复ACK,触发重传机制(快速重传或超时重传),并调整拥塞窗口(通常是快速重传降低cwnd,超时重传将cwnd和ssthresh大幅降低)。
3.1.1.2、接收方丢包
接收方处理正常,只是没有收到数据包。它发送的ACK会反映出序情况,发送方据此进行重传。

3.1.2、乱序到达

接收方缓存乱序的数据包,等待缺失的包到达后,按序提交给上层应用。SACK选项可以更高效地处理乱序。

3.1.3、重复包

可能由重传机制或网络环路引起。接收方通过序列号识别重复包,丢弃它们,但通常会发送最新的ACK。

3.1.4、超时重传

当发送方发送数据后,启动一个重传计数器(RTO)。如果在RTO时间内没有收到相应的ACK,就认为数据包丢失,触发超时重传。RTO的值会根据网络状况动态调整,以尽可能准确反映当前RTT。

3.1.5、连接异常中断

3.1.5.1、主动关闭方
进入FIN_WAIT_1,FIN_WAIT_2,TIME_WAIT状态。TIME_WAIT状态持续2*MSL(最大段生存时间),确保最后发出的FIN/ACK能够被对方收到,并防止旧连接的报文干扰新连接。
3.1.5.2、被动关闭方
进入CLOSE_WAIT,LAST_ACK状态。
3.1.5.3、一方崩溃
另一方可能因为长时间没有收到任何数据或ACK而超时关闭连接。
3.1.5.4、网络攻击
双方可能因为长时间无法通信而超时关闭。

3.1.6、SYN洪泛攻击

攻击者大量发送伪造源IP的SYN包,使服务器资源耗尽在等待完成三次握手。防御措施包括SYN Cookie、增加半连接队列大小、速率限制等。

3.1.7、RST包

重置包,用于强制关闭连接或拒绝非法连接请求。收到RST包的一方会立即关闭连接。

3.1.8、保活机制

长时间无数据交互时,发送方定期发送探测包,检测连接是否存活。

3.2、处理原则

TCP通过序列号、确认号、计时器、重传机制、状态机转换等一系列复杂的设计,来检测、诊断并恢复这些异常,尽力保证数据的可靠传输和连接的稳定关闭。

网站公告

今日签到

点亮在社区的每一天
去签到