大家好,这里是编程Cookbook。本文详细介绍计算机网络中的TCP/UDP协议相关的内容,包括单不限于基础概念、连接的建立与断开、TCP可靠传输的实现等。
TCP 可靠传输机制
TCP 协议的可靠传输机制
TCP 通过以下机制保证可靠传输:
- 序列号和确认机制:
- 每个字节的数据都有一个唯一的序列号。
- 接收方通过发送 ACK 报文确认已收到的数据。
- 超时重传:
- 发送方在发送数据后启动定时器,如果超时未收到 ACK,则重传数据。
- 流量控制:
- 通过滑动窗口机制,接收方动态调整发送方的发送速率,避免接收方缓冲区溢出。
- 拥塞控制:
- 通过慢启动、拥塞避免、快速重传和快速恢复等算法,动态调整发送速率,避免网络拥塞。
- 数据校验:
- 使用校验和字段检测数据在传输过程中是否损坏。
- 顺序传输:
- 通过序列号保证数据按顺序到达,接收方重新排序乱序到达的数据。
详细介绍如下:
关注公众号「编程Cookbook」,获取更多编程学习/面试资料!
1. 序列号(Sequence Number)和确认应答(ACK)
TCP 在每个数据包中使用序列号来标识数据的顺序。每个字节都被分配一个唯一的序列号,这样接收方能够知道哪些数据已经接收并按照正确的顺序进行重组。
- 当接收方收到数据时,确认数据的顺序,并根据序列号进行重排序(如果数据包乱序到达)。
- 如果丢失了某些数据包,接收方不会丢弃整个接收到的数据,而是根据序列号向发送方发送ACK,请求发送丢失的部分。
TCP 使用确认应答(ACK)机制来确保数据的可靠交付。每当接收方收到一个数据包时,它会返回一个带有 ACK 的消息,告诉发送方它成功收到了数据,并且确认收到的数据的序列号。
- 发送方发送数据后,等待接收方返回 ACK。
- 累积确认:ACK 可以确认多个数据包,接收方只需要确认最后一个按顺序到达的包。比如,如果接收方收到数据包 1、2、3,它只需要发送一个 ACK 来确认收到数据包 3。
- 如果发送方在超时时间内未收到 ACK,说明数据可能丢失或者延迟,发送方会进行超时重传。
2. 超时重传机制
TCP 通过超时重传来处理丢失的数据包。每个数据包都有一个与之关联的超时定时器,发送方在发送数据包后,会启动该定时器并等待接收方的 ACK。
- 如果发送方在超时时间内没有收到 ACK,它会认为数据包丢失,并重新发送该数据包。
- 超时时间(RTO,Retransmission Timeout) 是动态调整的,它基于往返时间(RTT)计算,确保合理的超时判断。
3. 流量控制(Flow Control)
TCP 通过流量控制机制来避免接收方处理不过来过快的数据流。流量控制使用滑动窗口(Sliding Window) 技术。
- 滑动窗口:表示接收方能够接受的最大数据量。发送方在发送数据时,不会超过接收方的窗口大小,这样可以避免接收方因为处理不了而丢失数据。
- 每次接收方成功接收到数据时,会将窗口大小通知发送方,从而动态调整发送的速度。
流量控制:关注的是发送方和接收方之间的速率匹配,防止接收方缓冲区溢出。
关注公众号「编程Cookbook」,获取更多编程学习/面试资料!
4. 拥塞控制(Congestion Control)
TCP 使用拥塞控制来避免网络发生拥塞,减少网络负载,并保证数据能够顺利传输。拥塞控制分为多个阶段:
- 慢启动(Slow Start):开始时,拥塞窗口较小,每收到一个 ACK,窗口大小就增加一倍,直到达到一个阈值。
- 拥塞避免(Congestion Avoidance):当窗口大小接近阈值时,增加速度变慢,避免网络过载。
- 快速重传和快速恢复:当检测到数据包丢失时,TCP 会快速重传丢失的数据包,并恢复到丢包前的状态,以减少网络拥塞带来的影响。
这些控制机制共同作用,保证数据的可靠传输,并尽量避免过度的网络拥塞和数据丢失。
拥塞控制:关注的是网络中的资源竞争,防止网络拥塞。
5. 数据包校验和(Checksum)
TCP 使用校验和来确保数据在传输过程中没有损坏。数据包的每一部分(包括头部和数据部分)都会进行校验,接收端计算接收到的 TCP 数据包的校验和,如果计算结果为零,说明数据在传输过程中未被破坏。否则,接收端会丢弃该数据包并要求重传。
- 校验和不仅用于传输数据内容,还包括了数据包的头部信息(如 IP 地址等)。
工作原理
-
计算校验和:
- 发送方将数据按 16 位分块,对所有块进行加法运算,若溢出则加到低位。
- 计算完成后,取反作为校验和,并存入数据包的校验字段。
-
校验过程:
- 接收方对收到的数据包进行相同计算(包含校验和字段)。
- 计算结果应为 全 0,否则说明数据出错,需重传。
6. 保证数据顺序(Order Preservation)
TCP 保证数据按发送顺序传输到接收方,并确保数据无乱序问题。由于 TCP 是面向字节流的,接收方会根据序列号对接收到的数据进行排序,并在顺序正确时交付给应用程序。
- 如果某个数据包在传输过程中丢失,接收方会通过 ACK 请求重传丢失的包,并不会交付乱序的数据。
TCP 超时重传机制
TCP 采用超时重传(Timeout Retransmission)机制来保证数据可靠传输,其核心目的是解决数据丢失或延迟过长的问题。
1. 解决的问题
当 TCP 发送的数据包在一定时间内没有收到确认 ACK,可能出现以下情况:
- 数据丢失:数据包在传输过程中丢失(网络拥塞、线路故障等)。
- ACK 丢失:数据包正确到达,但确认报文(ACK)丢失,导致发送方无法确定数据是否成功送达。
- 网络延迟:ACK 由于网络抖动或拥塞未及时返回,可能被误判为丢失。
为了解决上述问题,TCP 采用超时重传机制,即设定一个超时计时器,如果在超时时间内未收到 ACK,就重新发送数据包,确保数据最终到达。
关注公众号「编程Cookbook」,获取更多编程学习/面试资料!
2. 超时重传的核心机制
-
超时计时器(RTO,Retransmission Timeout):
- TCP 在每次发送数据时都会启动一个超时计时器。
- 如果在超时时间 RTO 内未收到 ACK,则重发该数据包。
-
RTO 计算(动态调整):
- 不能设太短,否则会因网络波动导致不必要的重传(影响性能)。
- 不能设太长,否则丢包恢复速度慢(影响传输效率)。
- TCP 采用自适应算法(基于往返时间 RTT)计算 RTO:
R T O = S R T T + 4 × R T T V A R RTO = SRTT + 4 \times RTTVAR RTO=SRTT+4×RTTVAR
其中:- SRTT(平滑往返时间):最近 RTT 采样的加权平均值。
- RTTVAR(往返时间偏差):RTT 的变化范围。
-
指数退避(Exponential Backoff):
- 若连续多次超时重传,TCP 指数级增加 RTO,避免频繁重传加重网络负担:
R T O n e w = 2 × R T O o l d RTO_{new} = 2 \times RTO_{old} RTOnew=2×RTOold
- 若连续多次超时重传,TCP 指数级增加 RTO,避免频繁重传加重网络负担:
3. 关键优化机制
- 快速重传(Fast Retransmit):收到3 次重复 ACK,立即重传数据包,无需等待超时。
- SACK(选择性确认):接收方告诉发送方哪些数据收到,减少不必要的重传。
- RTO 计算优化:RFC 6298 定义了更准确的 RTT 估计方法,避免误判。
TCP 快速重传机制
1. 超时重传的局限性
超时重传(Timeout Retransmission)是基于超时计时器来判断数据是否丢失的:
- 发送方在发送数据后,启动超时计时器(RTO)。
- 如果在RTO 时间内未收到 ACK,则认为数据丢失,重新发送。
- 但如果 RTO 设置过大,数据丢失后需要等很长时间才能触发重传,影响传输效率。
2. 快速重传的作用
快速重传(Fast Retransmit) 解决了超时重传等待时间过长的问题:
- 当接收方收到乱序数据(即中间数据丢失),会继续发送重复 ACK(Duplicate ACK)。
- 当发送方收到3 个相同的 ACK,就可以立即重传丢失的数据包,而不需要等 RTO 超时。
3. 超时重传 vs. 快速重传
特性 | 快速重传 | 超时重传 |
---|---|---|
触发条件 | 收到 3 个或更多重复的 ACK | 超时时间内未收到 ACK |
重传延迟 | 低(立即重传) | 高(等待超时时间) |
适用场景 | 数据包丢失但网络延迟较低 | 数据包丢失且网络延迟较高 |
性能影响 | 对传输性能影响较小 | 对传输性能影响较大 |
4. 为什么 TCP 需要快速重传?
- 提高数据传输效率:避免长时间等待 RTO 超时,提高网络吞吐量。
- 减少不必要的超时:当网络丢包率低时,RTO 设置一般较长,快速重传可以更快恢复数据传输。
- 与 SACK 结合减少冗余重传:快速重传可与 选择性确认(SACK) 一起使用,减少多余的重传数据量。
TCP 的 SACK(Selective Acknowledgment,选择性确认)机制
TCP 传统ACK机制的问题
TCP 传统的累计确认(ACK) 方式只能确认连续的字节流,但当网络发生丢包时,会导致不必要的重传。例如:
- 发送方发送 数据包 1, 2, 3, 4, 5。
Packet 2
丢失,而Packet 3, 4, 5
成功到达。- 接收方只能 发送 ACK1(表示仍然期待
Packet 2
),即使Packet 3, 4, 5
已经收到。 - 发送方超时重传
Packet 2
,但可能会重发Packet 3, 4, 5
,造成带宽浪费。
SACK 解决方案
SACK 允许接收方明确告诉发送方它 “收到了哪些非连续的数据块” ,从而:
- 让发送方只重传丢失的数据,避免不必要的重传。
- 提高带宽利用率,减少网络拥塞。
3. SACK 机制的工作方式
SACK 通过TCP 选项字段扩展,格式如下:
TCP 头部
| 源端口 | 目标端口 |
| 序列号 |
| 确认号 |
| 头部长度 | 保留字段 | 控制位 | 窗口大小 |
| 校验和 | 紧急指针 |
| 选项字段 (SACK 选项) |
SACK 选项格式:
Kind = 5(SACK 选项标识符)
Length = 2 + 8*N (每个块占 8 字节)
左边界 1(开始序列号)
右边界 1(结束序列号)
左边界 2(开始序列号)
右边界 2(结束序列号)
...
示例
假设发送方发送 Packet 1-5
,但 Packet 2
丢失:
- 接收方成功接收
Packet 3, 4, 5
,发送如下 SACK:ACK1 + SACK(3-5)
- 发送方看到 SACK 后,只重传
Packet 2
,避免Packet 3-5
被重传。
关注公众号「编程Cookbook」,获取更多编程学习/面试资料!
4. SACK 和快速重传的关系
- 快速重传 触发提前重传,但仍然会多余地重传数据。
- SACK 能够精确定位丢失的数据,让发送方只重发必要的部分,减少冗余流量。
5. 总结
机制 | 作用 | 优势 | 局限 |
---|---|---|---|
累计确认 (ACK) | 只确认最早的连续数据 | 兼容性好,简单 | 无法处理乱序数据,高丢包时效率低 |
快速重传 | 3 个重复 ACK 触发重传 | 提前重传丢包数据 | 可能导致多余重传 |
SACK | 选择性确认已接收数据块 | 避免冗余重传,节约带宽 | 需要额外 TCP 选项字段 |
流量控制
流量控制的概念
流量控制(Flow Control) 是 TCP 发送方和接收方之间的一种机制,确保发送方不会发送过多数据,导致接收方处理不过来。
- 目标:防止接收方的缓冲区溢出,导致数据丢失。
- 方式:TCP 采用**滑动窗口(Sliding Window)**进行流量控制。
TCP 如何实现流量控制?
TCP 通过**接收窗口(Receive Window, rwnd)**实现流量控制:
- 接收方维护一个接收窗口(rwnd),表示当前还能接收的字节数。
- 发送方根据接收方的窗口大小发送数据,不超过 rwnd 的限制。
- 窗口更新:每次接收方处理完数据后,通知发送方新的窗口大小。
流量控制示例
1. 发送方发送 1000 字节数据,接收方缓冲区大小 500 字节。
2. 发送方必须等待接收方处理完 500 字节后,窗口更新,才能继续发送数据。
流量控制的核心是接收窗口的动态调整,确保数据流不会超出接收方的处理能力。
滑动窗口
滑动窗口(Sliding Window)的概念
滑动窗口是一种流量控制机制,用于管理 TCP 连接中的数据传输。
它允许发送方在不等待 ACK 的情况下,连续发送多个数据包,提高传输效率。
滑动窗口的作用
- 提高传输效率:避免每发送一个数据包就等待 ACK,减少延迟。
- 控制流量:防止接收方处理不过来,避免丢包。
- 支持流式数据传输:如视频流、文件传输等。
TCP 滑动窗口示例
假设窗口大小(rwnd)为 4000 字节,数据以 1000 字节为单位:
1. 发送方连续发送 P1(1000B), P2(1000B), P3(1000B), P4(1000B)。
2. 发送窗口满了,等待 ACK。
3. 接收方处理 P1,ACK 1000B,窗口滑动,发送方继续发送 P5(1000B)。
滑动窗口 = 已发送但未确认的数据 + 可发送的数据
滑动窗口的三部分
窗口部分 | 作用 |
---|---|
已发送并确认 | 发送方已收到 ACK,可释放 |
已发送但未确认 | 需要等待 ACK |
可发送但未发送 | 发送方可以立即发送 |
TCP 拥塞控制的步骤
什么是拥塞控制?
拥塞控制(Congestion Control)是 TCP 为了防止网络拥堵 而采用的流量控制机制,目的是避免过多数据包进入网络,导致丢包和延迟增加。
关注公众号「编程Cookbook」,获取更多编程学习/面试资料!
TCP 拥塞控制的四个阶段
TCP 拥塞控制主要包括 慢启动(Slow Start)、拥塞避免(Congestion Avoidance)、快速重传(Fast Retransmit)、快速恢复(Fast Recovery) 四个阶段。
阶段 | 描述 |
---|---|
1. 慢启动(Slow Start) | 初始发送窗口(cwnd)从小值(通常 1 MSS)开始,每次 ACK 到达时指数增长。 |
2. 拥塞避免(Congestion Avoidance) | 当 cwnd 超过阈值(ssthresh)后,改为线性增长,防止网络拥塞。 |
3. 快速重传(Fast Retransmit) | 发送方收到3 个重复 ACK,立即重传丢失数据,而不等待超时。 |
4. 快速恢复(Fast Recovery) | 重传后,ssthresh 降为当前 cwnd/2,cwnd 设为 ssthresh + 3(或类似调整),然后进入拥塞避免阶段(而非慢启动)。(这是 TCP Reno 与早期 Tahoe 的主要区别)。 |
以下是各阶段的详细说明:
1. 慢启动(Slow Start)
- 目的:快速探测网络可用带宽,避免一开始就发送大量数据导致拥塞。
- 工作原理:
- 发送方从 初始拥塞窗口(cwnd = 1 MSS)开始,每收到一个 ACK,cwnd 指数增长(
cwnd *= 2
)。 - 增长直到达到 慢启动阈值(ssthresh) 或检测到拥塞(丢包)。
- 发送方从 初始拥塞窗口(cwnd = 1 MSS)开始,每收到一个 ACK,cwnd 指数增长(
- 触发条件:
- 新连接建立时。
- 超时重传(RTO)后。
- 特点:
- 窗口大小呈指数增长(1 → 2 → 4 → 8…)。
2. 拥塞避免(Congestion Avoidance)
- 目的:避免因窗口过大导致网络拥塞,转为线性增长。
- 工作原理:
- 当
cwnd >= ssthresh
时,每 RTT(往返时间)窗口线性增长(cwnd += 1 MSS
)。 - 若检测到拥塞(丢包),将
ssthresh
设为当前cwnd/2
,并进入快速恢复
或重新慢启动
。
- 当
- 触发条件:
- 慢启动阶段达到
ssthresh
。
- 慢启动阶段达到
- 特点:
- 窗口大小线性增长(避免激进发送)。
例子
(1)慢启动阶段(Slow Start)
- 窗口增长方式:指数增长(每 RTT
cwnd *= 2
)。 - 图中表现:
cwnd
从 1 开始,快速增加到 4、8、16(接近初始ssthresh=16
)。- 当
cwnd
达到ssthresh=16
时,切换到 拥塞避免 阶段。
(2)拥塞避免阶段(Congestion Avoidance)
- 窗口增长方式:线性增长(每 RTT
cwnd += 1 MSS
)。 - 图中表现:
cwnd
从 16 开始,逐步增加到 18、20、22…(“加法增大”)。- 当发生 网络拥塞(如丢包)时,触发“乘法减小”:
ssthresh
降为当前cwnd/2
(图中新ssthresh=12
)。cwnd
重置为 1,重新进入 慢启动。
(3)重新慢启动
- 图中表现:
cwnd
从 1 再次指数增长(2、4、8…),直到达到新的ssthresh=12
。- 之后可能再次进入拥塞避免阶段(图中未完全展示)。
3. 快速重传(Fast Retransmit)
-
目的:快速修复丢包,避免等待超时(RTO)。
-
工作原理:
- 发送方连续收到 3 个重复 ACK(DupACK)时,立即重传丢失的报文段。
- 无需等待超时计时器触发。
-
触发条件:
- 检测到部分丢包(非连续丢包)。
-
特点:
- 显著减少重传延迟(相比 RTO 超时)。
-
详细流程参考下图
4. 快速恢复(Fast Recovery)
-
目的:在快速重传后避免过度降低发送速率,平滑恢复流量。
-
工作原理:
- 重传丢失报文后,将
cwnd
设为ssthresh + 3 MSS
(补偿已收到的 DupACK)。 - 每收到一个 DupACK,
cwnd += 1 MSS
(允许发送新数据)。 - 收到新数据的 ACK 后,退出快速恢复,将
cwnd
设为ssthresh
,进入拥塞避免阶段。
- 重传丢失报文后,将
-
触发条件:
- 快速重传后。
-
特点:
- 避免窗口骤降,保持较高吞吐量。
-
详细流程参考下图
四个阶段的协同流程
- 慢启动(窗口翻2倍增长) → 达到
ssthresh
→ 拥塞避免(线性增长)。 - TCP Tahoc (已废弃)版本:检测到 超时丢包 → 重置
cwnd=1
,重新进入 慢启动。 - TCP Reno 版本:检测到 3 个 DupACK → 快速重传 → 快速恢复。
关注公众号「编程Cookbook」,获取更多编程学习/面试资料!
TCP 中的 RST (reset) 报文
1. 什么是 RST 报文?
RST(Reset,复位)是 TCP 控制标志位之一,用于强制终止 TCP 连接。当一方收到 RST 报文时,意味着:
- 连接被异常关闭,不能再继续通信。
- 任何未确认的数据都会被丢弃。
RST 报文的特点:
- 不需要四次挥手,可以立即终止连接。
- 不会进行重传,一旦发送,接收方必须立刻丢弃连接状态。
2. 什么时候会出现 RST 报文?
RST 报文通常在以下情况下出现:
场景 | 描述 |
---|---|
端口未监听 | 客户端连接到一个未监听的端口,服务器返回 RST。 |
连接异常关闭 | 一方进程崩溃、服务器宕机,导致连接突然终止。 |
错误的数据包 | TCP 报文的序列号超出窗口范围,可能被视为攻击,返回 RST。 |
长时间未通信 | NAT 设备或防火墙关闭空闲连接,导致 RST。 |
过载保护 | 服务器过载,主动丢弃连接,发送 RST 释放资源。 |
ARQ (自动重传请求)协议
1. 什么是 ARQ 协议?
ARQ(自动重传请求)是一种可靠数据传输协议,用于解决数据在不可靠信道(如网络、无线通信)上的丢失或错误传输问题。
核心思想:
- 发送方发送数据后,等待接收方确认(ACK)。
- 如果未收到确认或检测到错误,则重新发送数据包。
2. ARQ 协议的主要类型
ARQ 主要有以下三种类型:
协议 | 特点 | 优缺点 |
---|---|---|
停等 ARQ(Stop-and-Wait ARQ) | 每次发送一个数据包,等待 ACK 后再发送下一个 | 简单易实现,但吞吐率低 |
回退 N(Go-Back-N)ARQ | 允许连续发送多个数据包,若丢失,重发该数据包及其后续数据包 | 提高吞吐率,但重传代价大 |
选择性重传(Selective Repeat)ARQ | 只重传丢失的特定数据包,避免重复发送已正确接收的数据 | 需要额外缓存,复杂度高 |
UDP 实现可靠传输
UDP(User Datagram Protocol)是无连接、不可靠的传输协议,不提供数据确认、重传、流量控制等机制。
但是,在实际应用中,某些应用层协议或自定义机制可以在 UDP 之上实现可靠传输。
UDP 可靠传输的常见实现方式
UDP 本身不提供可靠性,但可以通过应用层协议或额外机制实现,如下:
机制 | 作用 |
---|---|
应用层 ACK 确认 | 发送方等待接收方确认(ACK),超时重传丢失数据。 |
超时重传 | 发送方在未收到 ACK 时,重新发送数据包。 |
序列号机制 | 解决 UDP 乱序问题,确保数据按顺序到达。 |
滑动窗口 | 控制数据流,避免网络拥塞。 |
前向纠错(FEC) | 通过冗余信息(如 Reed-Solomon 码)修复丢失数据。 |
实际应用中的 UDP 可靠传输协议
协议 | 可靠性机制 | 应用场景 |
---|---|---|
TFTP | 超时重传 + ACK 机制 | 简单文件传输 |
RTP + RTCP | 序列号 + 误码控制 + FEC | 实时音视频流 |
QUIC(Google) | 流控 + 可靠传输(ACK + 重传) | 替代 TCP(如 HTTP/3) |
SRT(Secure Reliable Transport) | ARQ + FEC + 流控 | 低延迟视频传输 |
其他
TCP 的粘包和拆包问题
定义
在 TCP 传输过程中,应用层读取数据时,可能一次性接收到多个数据包(粘包),或者只接收到部分数据包(拆包),这就是 TCP 的粘包和拆包问题。
- 粘包(Packet Merging):多个发送的数据包被合并成一个,导致接收方无法正确解析数据边界。
- 拆包(Packet Splitting):一个完整的数据包被拆成多个部分发送,导致接收方读取到的数据不完整。
TCP 是基于流(Stream)的协议,数据是无边界的字节流,而应用层需要自己定义数据边界,因此会出现粘包和拆包的问题。
原因
TCP 不会按照应用层数据的逻辑边界 进行拆分和组装,而是尽量高效地利用网络资源,导致可能发生粘包或拆包。
- 粘包的原因:
- 发送方:TCP 协议为了提高传输效率,可能会将多个小数据包合并成一个大数据包发送(Nagle 算法)。
- 接收方:接收方的缓冲区较大,可能会一次性接收多个数据包。
- 拆包的原因:
- 发送方:数据包的大小超过了 TCP 的最大报文段长度(MSS)。
- 接收方:接收方的缓冲区较小,无法一次性接收完整的数据包。
解决方案
- 固定长度:
- 每个数据包都固定为相同的长度,不足部分用填充字符补齐。
- 优点:简单易实现。
- 缺点:浪费带宽。
- 分隔符:
- 在每个数据包的末尾添加特殊的分隔符(如换行符)。
- 优点:实现简单。
- 缺点:分隔符不能出现在数据内容中。
- 长度字段:
- 在每个数据包的头部添加一个长度字段,表示数据包的长度。
- 优点:灵活高效。
- 缺点:实现稍复杂。
UDP 为什么不会发生粘包和拆包?
UDP 是面向数据报(Datagram)的协议,每个 sendto()
发送的数据就是一个完整的 UDP 数据包,不会被合并或拆分,因此不会发生 TCP 那样的粘包和拆包问题。
-
UDP 没有粘包问题:
- 每个 UDP 数据包独立,
有明确的边界
。 - 接收方通过 UDP 首部来区分不同的消息。
- 每个 UDP 数据包独立,
-
UDP 不会有拆包问题:
- UDP 协议本身不会导致拆包问题,但如果数据报文超过 MTU,可能会发生 IP 分片。拆包问题通常发生在 IP 层,当一个 UDP 数据包的大小超过了 MTU(最大传输单元),会被 IP 层进行 分片,但这并不是 UDP 协议本身的行为,而是由 IP 协议层来处理的。
- 如果需要传输较大的数据,可以限制 UDP 数据包大小或在应用层进行拆分与重组,以避免 IP 层分片的影响。
关注公众号「编程Cookbook」,获取更多编程学习/面试资料!
浏览器的 TCP 连接限制
浏览器对同一 Host 的 TCP 连接数量限制
- HTTP/1.1:
- 大多数浏览器对同一 Host 的 TCP 连接数量限制为 6-8 个。
- 例如,Chrome 和 Firefox 默认限制为 6 个。
- 这个限制是基于 RFC 2616(HTTP/1.1 规范)的建议,以避免客户端对服务器造成过大的负载。
- HTTP/2:
- HTTP/2 使用多路复用(Multiplexing)技术,允许在单个 TCP 连接上并行传输多个请求和响应。
- 因此,HTTP/2 通常只需要 1 个 TCP 连接,不再受限于 6-8 个连接。
为什么要有连接数量限制?
- 减少服务器负载:
- 如果每个客户端都创建大量 TCP 连接,服务器可能会因为维护过多的连接而耗尽资源。
- 优化网络性能:
- 过多的 TCP 连接会增加网络拥塞和延迟。
- 限制连接数量可以更好地利用带宽和连接资源。
- 遵循 HTTP/1.1 规范:
- HTTP/1.1 规范建议客户端对同一 Host 的连接数量进行限制,以提升整体性能。
如何绕过连接数量限制?
- 使用 HTTP/2:
- HTTP/2 的多路复用技术可以绕过连接数量限制,因为所有请求都可以通过单个 TCP 连接并行传输。
- 域名分片(Domain Sharding):
- 将资源分布在多个子域名下,例如:
static1.example.com
static2.example.com
- 每个子域名可以建立 6-8 个 TCP 连接,从而增加总连接数。
- 注意:域名分片会增加 DNS 查询和 TCP 连接的开销,因此在 HTTP/2 中不推荐使用。
- 将资源分布在多个子域名下,例如:
- 增加浏览器连接限制:
- 可以通过修改浏览器配置(如 Chrome 的
--max-connections-per-host
参数)增加连接限制,但这通常不推荐。
- 可以通过修改浏览器配置(如 Chrome 的
关注公众号「编程Cookbook」,获取更多编程学习/面试资料!