TCP 传输可靠性保障(传输层)
TCP 如何保证传输的可靠性?
TCP 协议通过多个机制来确保数据传输的可靠性。以下是其主要方式:
1. 基于数据块传输
TCP 将应用数据分割成较小的单元,称为 报文段。这些报文段被送往网络层进行传输。每个报文段都有一个 序列号,用于标识数据的顺序。这有助于接收方重新组合数据,并保证数据按正确顺序到达。
2. 对失序数据包重新排序以及去重
TCP 使用 序列号 来标识每个数据包的顺序。接收方通过序列号对接收到的数据进行排序,确保数据能够按正确顺序重组。此外,接收方能够识别重复的数据包,并丢弃它们,从而避免数据冗余和重复接收。
3. 校验和
TCP 在数据传输中使用 校验和 来保证数据的完整性。每个报文段都会计算一个校验和,发送方在发送报文时将校验和附加在报文头部,接收方在接收到报文后会重新计算校验和并与报文中的校验和进行对比。如果校验和不匹配,说明数据在传输过程中发生了错误,接收方会丢弃该数据包,并不会确认收到该报文段。
4. 重传机制
TCP 提供了可靠的数据传输机制,确保即使数据包丢失,传输过程依然能继续。其主要重传机制包括:
- 超时重传:如果发送方在规定的时间内没有收到接收方的确认应答(ACK),就会重发该数据包。重传的时机和重传次数受到 超时定时器 控制。
- 快速重传:当接收方接收到不按顺序到达的数据包时,会立即发送 重复 ACK,通知发送方某个包丢失,进而触发重传机制。
- SACK(选择性确认):在快速重传机制的基础上,接收方会在重复 ACK 中携带一段范围信息,告诉发送方哪些数据包已经成功接收,哪些数据包丢失。这可以减少不必要的重传。
- D-SACK(重复选择性确认):D-SACK 是 SACK 的扩展,除了返回丢失数据包的序列号范围外,还会通知发送方接收到重复的包,以帮助发送方识别哪些数据包被多次接收。
5. 流量控制
流量控制机制用于防止接收方的缓冲区溢出。每一方 TCP 连接都有一个固定大小的缓冲区,接收方通过一个 滑动窗口 协议通知发送方自己可以接收的最大数据量。如果接收方的缓冲区已满,它会通知发送方减少数据发送的速度。滑动窗口协议是一种动态调整机制,根据接收方的接收能力灵活地调节发送的数据量。
6. 拥塞控制
拥塞控制机制用于应对网络拥塞,防止网络过载。TCP 在发送数据时,考虑到两个关键因素:
- 接收方的能力:通过滑动窗口来表示接收方的接收能力。
- 网络的拥塞程度:通过 拥塞窗口 来控制发送方在网络中能够发送的数据量。拥塞窗口由发送方动态计算,表示它认为可以安全发送的数据量。
TCP 通过以下几种算法来控制拥塞:
- 慢启动:TCP 从一个较小的拥塞窗口开始逐渐增大,直到达到网络的最大传输能力。
- 拥塞避免:当网络出现拥塞迹象时,TCP 会减小拥塞窗口,从而减少数据发送量,避免网络进一步拥塞。
- 快重传与快恢复:当 TCP 收到重复的 ACK 时,发送方会触发快速重传,并立即将拥塞窗口减半,以避免过多数据传输。
总结
TCP 通过 序列号、校验和、重传机制、流量控制、拥塞控制 等多个机制,确保了数据在传输过程中的可靠性。这些机制相互配合,不仅保证了数据的准确传输,还能够根据网络状况和接收方能力动态调整传输行为,从而避免数据丢失、重复和拥塞。
TCP 如何实现流量控制?
流量控制是 TCP 协议为了防止发送方发送数据过快,而导致接收方无法及时处理或缓冲区溢出的机制。它通过 滑动窗口 来动态调整数据的传输速率,确保发送方与接收方之间的流量平衡。
1. 流量控制的目标
流量控制的核心目标是防止数据丢失和确保双方通信的平稳:
- 接收方的缓冲区管理:接收方通常有一个固定大小的缓冲区。如果发送方发送数据的速率过快,接收方的缓冲区可能会被填满,导致数据丢失。
- 缓冲区溢出与丢包:当缓冲区满时,接收方可能会丢弃后续接收到的数据,从而导致丢包和网络资源浪费。
2. 滑动窗口机制
TCP 使用 滑动窗口 来实现流量控制。每一方(客户端和服务器)都维护一个发送窗口和接收窗口,窗口大小通过对方的反馈进行调整。
- 发送方:发送方的发送窗口限制了在没有接收确认的情况下,可以连续发送的数据量。发送方会根据接收方反馈的窗口大小来调整自己的发送速率。
- 接收方:接收方维护一个接收窗口,表示它目前能够接收的最大数据量。如果接收窗口变小,意味着接收方的缓冲区空间有限,发送方应减少发送数据的速率。
3. 窗口大小的动态调整
窗口大小不是固定的,而是 动态调整 的。接收方在每个确认报文中都会包含当前的接收窗口大小,告诉发送方它能接收多少数据。
- 接收方的接收能力:当接收方有足够的缓存空间时,它会通过增大接收窗口来允许发送方发送更多的数据。反之,当缓冲区快满时,它会减小接收窗口的大小,甚至将窗口设置为 0,告知发送方暂停发送。
- 发送方的响应:发送方收到接收方反馈的接收窗口大小后,决定是否继续发送数据。如果接收窗口大小为 0,发送方必须停止发送,直到接收方的窗口再次增大。
4. TCP 窗口的组成
在实际操作中,发送方和接收方的窗口被划分为多个区域:
- 发送方窗口:发送方的窗口包括已发送但未确认的数据、已确认的数据,以及可以发送的数据。发送窗口的大小会受到接收方的窗口和网络状况的影响。
- 接收方窗口:接收方的窗口包括可以接收的数据以及不可接收的数据。接收方根据自身的缓冲区空间动态调整接收窗口的大小。
5. 如何工作
假设发送方发送了数据 A
、B
和 C
:
- 发送方发送数据
A
和B
,并等待确认。接收方确认并告知接收窗口的大小。 - 如果接收方的接收窗口大小足够,它会告诉发送方继续发送更多的数据(如
C
)。 - 如果接收方的缓冲区被填满,接收窗口会缩小,甚至变为 0,发送方此时会暂停发送数据,直到接收方的窗口大小恢复。
6. 滑动窗口的控制方式
滑动窗口 的控制主要依赖于以下几个参数:
SND.WND:发送窗口大小,表示发送方可以发送但未确认的最大数据量。
Rcv.WND:接收窗口大小,表示接收方可以接收的最大数据量。
SND.UNA:发送未确认数据的序列号,指示已发送但尚未被确认的数据的序列号。
SND.NXT:发送方下一次发送的数据序列号,指示下一个可以发送的数据包序列号。
发送方根据接收方的 Rcv.WND
(接收窗口)来决定可以发送的最大数据量。每次接收到确认报文,发送窗口会调整,确保不会超出接收方的处理能力。
7. 流量控制与拥塞控制的区别
流量控制和拥塞控制虽然有些相似,但它们的目的不同:
- 流量控制:主要关注接收方的缓冲区,确保发送方的发送速率与接收方的处理能力匹配。
- 拥塞控制:主要关注网络本身的拥塞情况,避免因为过多的数据流入网络而导致网络拥塞。
8. 总结
流量控制是 TCP 确保稳定和可靠数据传输的关键机制。通过滑动窗口的动态调整,TCP 保证了发送方的发送速率不会超出接收方的处理能力。接收方通过在每个确认包中返回的窗口大小来控制发送方的数据流,从而避免了因接收方缓冲区溢出而造成的数据丢失。
TCP 的拥塞控制是怎么实现的?
TCP 的拥塞控制旨在避免网络过载,通过动态调整数据传输的速率来保证网络的稳定性。其核心目标是防止过多的数据被发送到网络中,避免网络拥塞,从而保证网络资源的有效利用。
在 TCP 中,发送方维护一个 拥塞窗口(cwnd),该窗口的大小表示可以发送的最大数据量。拥塞窗口的大小受网络状况(如拥塞程度)影响,动态调整。当发送方发送数据时,它会根据 拥塞窗口 和 接收窗口(rwnd) 的大小来决定实际的发送数据量。实际的窗口大小是 cwnd 和 rwnd 中的最小值。
TCP 的拥塞控制主要通过四种算法来实现:
1. 慢开始(Slow Start)
慢开始算法的核心思想是逐步增大发送数据的速率,以避免在一开始就向网络发送过多的数据。初始时,cwnd 的大小设为 1,每当收到一个 ACK,拥塞窗口会加倍增长。这个过程在网络环境不稳定的初期非常有效,因为它能够通过慢速探测来适应当前的网络条件。
具体过程:
- 初始时,cwnd 设为 1。
- 每收到一个确认(ACK),cwnd 就加倍。
- 随着 cwnd 的增加,TCP 会逐步探测出合适的网络负载,减少发送数据的速率。
2. 拥塞避免(Congestion Avoidance)
当 cwnd 达到一个阈值(ssthresh,慢开始阈值)后,进入 拥塞避免 状态。此时,拥塞窗口增长的速度将会减缓,不再以指数级的方式增加,而是线性增加。每经过一个往返时延(RTT),cwnd 增加一个 MSS(最大报文段大小)。
具体过程:
- 如果 cwnd 达到 ssthresh,则采用线性增长的方式,每 RTT 增加 1 MSS。
- 这种增长策略减少了网络过载的风险,但比慢开始更为保守。
3. 快重传与快恢复(Fast Retransmit and Fast Recovery)
快速重传和快速恢复算法旨在快速处理数据包丢失的情况。当接收方收到一个重复的确认(即对同一数据包的确认),它会立即发送一个 ACK 给发送方,告诉发送方发生了丢包。发送方在收到三个重复的 ACK 后,认为有数据包丢失,并立即重传该数据包。
具体过程:
- 发送方在接收到三个重复的 ACK 时,会立即重传丢失的数据包。
- 在快速恢复阶段,cwnd 会减半,这种做法会迅速减少网络拥塞,恢复数据的传输。
- 快速重传和恢复避免了传统的超时重传机制,通过提前识别丢包和减少拥塞窗口的方式加速恢复过程。
4. 慢开始阈值(ssthresh)与窗口调整
- 慢开始阈值(ssthresh) 是 TCP 在慢开始阶段和拥塞避免阶段之间的过渡点。其默认值通常是网络中的最大窗口大小。当 cwnd 达到 ssthresh 时,拥塞控制由 慢开始 转为 拥塞避免,从而实现更平稳的网络流量控制。
- 如果发生丢包(通过快重传触发),ssthresh 会被调整为当前 cwnd 大小的一半。此时,cwnd 会重置为 1,重新进入慢开始阶段。
拥塞控制过程示意
初始阶段:
- 初始时,cwnd 较小,慢开始逐步探测网络状况。
- 每次收到 ACK,cwnd 迅速加倍。
达到阈值:
- 一旦 cwnd 达到 ssthresh,TCP 会切换到拥塞避免状态,增速变慢(线性增长)。
丢包检测:
- 当网络出现丢包时,发送方通过 快速重传 得知丢包的发生,立即重传丢失的数据。
- cwnd 会减半,进入 快速恢复,确保网络负载被及时减小,避免更大规模的丢包。
小结
TCP 的拥塞控制通过动态调整 cwnd 来控制数据发送的速率,避免网络过载和数据包丢失。它利用 慢开始、拥塞避免、快重传 和 快恢复 四种算法,结合 ssthresh(慢开始阈值)调整窗口大小,确保网络在不同负载下的稳定性和效率。
ARQ 协议概述
自动重传请求(ARQ)协议是一种基于确认和超时机制的可靠数据传输协议。它通过重传机制确保数据的可靠传输,适用于不可靠的通信环境。ARQ 协议通过发送方在发送数据后等待接收方的确认(ACK),如果未收到确认,发送方会在超时后重传数据,直到接收到确认或达到最大重试次数。
ARQ 协议主要包括以下两种类型:
1. 停止等待 ARQ 协议(Stop-and-Wait ARQ)
停止等待协议是最简单的 ARQ 协议。在这种协议中,发送方每次只发送一个数据包,并等待接收方的确认。如果在规定的超时时间内没有收到确认,发送方会重传该数据包。接收方收到数据后,返回一个确认消息,如果数据包丢失或发生错误,接收方会丢弃该包。
工作过程
无差错情况:
- 发送方发送一个数据包,接收方正确收到后返回确认(ACK)。
- 发送方收到确认后,发送下一个数据包。
差错情况(超时重传):
- 如果发送方在超时时间内未收到确认,会认为数据包丢失或传输失败,并重传该数据包。
确认丢失与确认迟到:
- 确认丢失:如果接收方的确认消息丢失,发送方会在超时后重传数据包。接收方在收到重复数据包后会丢弃,并重新发送确认。
- 确认迟到:如果确认消息迟到,发送方会在收到确认后继续发送数据,而接收方也会丢弃重复的数据包。
优缺点
优点:
- 实现简单。
- 确保每个数据包都被正确接收。
缺点:
- 发送方每次只能发送一个数据包,等待确认后才能发送下一个,效率较低。
- 高延迟情况下,可能导致信道利用率低。
2. 连续 ARQ 协议(Continuous ARQ)
连续 ARQ 协议改进了停止等待协议,通过发送方使用一个发送窗口来提高信道的利用率。发送方可以连续发送多个数据包,而不必等待每个数据包的确认。接收方通常采用累计确认方式,即确认最后一个按序到达的包,表示所有之前的数据包都已经正确接收。
工作过程
- 发送方在窗口内可以同时发送多个数据包。
- 接收方收到数据后,按照顺序发送累计确认(ACK),告知发送方已成功接收的数据包。
- 发送方可以根据确认收到的数据包,滑动发送窗口,继续发送新的数据包。
优缺点
优点:
- 信道利用率高,可以同时发送多个数据包。
- 避免了等待每个数据包的确认,减少了等待时间。
缺点:
- 如果发生丢包,发送方只能根据接收方的累计确认来推断丢失的包,导致发送方可能需要重传多个数据包。通常采用 Go-Back-N 机制,即重传从丢失包开始的所有后续包。
Go-Back-N ARQ
在连续 ARQ 协议中,Go-Back-N 是一种常见的实现方式。它的主要特点是:如果发送方发现某个包丢失,它会重传从丢失包开始的所有后续包。
工作过程
- 发送方会保持一个发送窗口,允许发送多个数据包。
- 接收方每次只确认最后一个按序到达的包,确保所有之前的包都已接收。
- 如果某个包丢失,接收方会丢弃该包及其后续的所有包,发送方会重传丢失的包及其后续包。
小结
ARQ 协议通过确认和超时机制来确保数据可靠传输。停止等待 ARQ 实现简单,但效率低,适用于低延迟、低带宽的环境;而 连续 ARQ(如 Go-Back-N)则通过引入发送窗口和累计确认,显著提高了信道利用率,但可能需要更多的重传和处理丢包的逻辑。
超时重传的实现
在 TCP 协议中,超时重传(Timeout Retransmission)用于确保数据包能够可靠地传输到接收方。其实现过程如下:
- 发送数据包:当发送方发送一个数据包后,启动一个定时器,等待接收方的确认(ACK)。
- 接收确认:接收方收到数据包后,发送确认消息(ACK)回发送方。
- 等待超时:如果发送方在设定的时间内没有收到 ACK 确认,它会认为数据包丢失或发生了传输错误。
- 重传数据包:在超时后,发送方会重新发送丢失的数据包,继续等待确认。
超时重传时间的确定
确定重传超时(RTO,Retransmission Timeout)是超时重传的关键,它决定了发送方在重传数据包之前的等待时间。RTO 的设置既不能太小(避免不必要的重传),也不能太大(避免过长的延迟)。RTO 的确定通常会通过网络往返时延(RTT,Round Trip Time)的测量来动态调整。
RTO 的计算方法
TCP 使用以下几种方法来估算 RTO:
加权移动平均(EWMA)算法
- RTT 是通过测量数据包的往返时间来估算的。
- RTO 是根据 RTT 和其变化动态调整的。
算法步骤:
- 每次收到新的 ACK 后,更新 RTT 的估算值。
- 使用加权移动平均法(EWMA)来计算 RTT 的估算值:
RTTₘ = (1 - α) * RTTₘ₋₁ + α * SampleRTT
- 其中,
RTTₘ
为最新的估算 RTT,SampleRTT
为当前测量得到的往返时延,α 是一个平滑因子,通常取值 0.125。
计算 RTO
- 计算 RTT 的偏差(RTT 的变化量),即 RTT 的标准差(RTT Variance):
RTTvarₘ = (1 - β) * RTTvarₘ₋₁ + β * |RTTₘ - RTTₘ₋₁|
- 其中,
RTTvarₘ
为当前的 RTT 偏差,β 通常取值 0.25。
- 最后,使用 RTT 和 RTT 偏差来计算 RTO:
RTO = RTTₘ + max(4 * RTTvarₘ, G)
- 其中,
G
是一个最小的保证时间,通常取值为 1 秒,确保 RTO 不会设置得过低。
- 计算 RTT 的偏差(RTT 的变化量),即 RTT 的标准差(RTT Variance):
Karn 算法
- Karn 算法 是为了处理因重传造成的 RTT 测量不准确问题。当发送方重传一个数据包时,收到的 ACK 可能是重传数据包的确认,因此其 RTT 测量值并不可靠。Karn 算法的核心是:
- 不使用重传包的 RTT 来更新 RTT 的估算值。
- 重传包的超时和重传次数会根据已知的 RTT 来动态计算 RTO。
- Karn 算法 是为了处理因重传造成的 RTT 测量不准确问题。当发送方重传一个数据包时,收到的 ACK 可能是重传数据包的确认,因此其 RTT 测量值并不可靠。Karn 算法的核心是:
Jacobson 算法
- Jacobson 算法 在加权移动平均的基础上进一步调整,提出了动态调整 RTO 的模型,考虑了网络的波动性和RTT的变化。通过不断调整 RTT 和 RTT 的变化量,Jacobson 算法提供了一种更加稳定的 RTO 估算方法。
总结
超时重传通过等待 ACK 来确保数据的可靠传输。如果 ACK 在预定时间内没有到达,发送方会启动重传机制。RTO 的计算非常关键,它需要根据 RTT 的测量值以及网络的波动性进行动态调整,以确保合适的重传时机。通过加权移动平均(EWMA)算法、Karn 算法和 Jacobson 算法,TCP 能够准确地估算 RTO,从而提高网络的传输效率并降低不必要的重传。