TCP 传输、重传及工作原理

网络
TCP具有快速重传功能 - 在计时器到期之前重新传输丢失的段,为了允许快速重传,我们需要为发送方和接收方设置一些规则。

IP和MAC层的内存受限,用于发送数据包。因此,它们都会限制消息的长度。

这一限制要求TCP在提供给IP层之前,将可变长度的字节打包成多个段。每个段的长度应该是合适的。

下面是一个简单的图示,展示了段是如何通过互联网发送的。

1*IRdfZ4LKKpQ-KRz_Y3QR7g.png

客户端的HTTP层正在向目标服务器发送一个18字节的流。

当字节16-18尚未到达TCP层时,字节12-15通过了它。TCP将它们打包成一个段,并附加了一个TCP头,标记在黄色区域。

接下来,该段被IP层封装,通过互联网发送,然后到达服务器。

假设TCP段的长度超过了底层支持的长度。在这种情况下,IP层将负责将大段拆分成多个片段。这是一个昂贵的过程,因此我们希望避免这种情况。

但是TCP如何确定长度呢?这取决于最大段大小(MSS)。

理想情况下,我们希望选择一个最大化数据量、最小化头部比例并避免在IP层进一步拆分的MSS。

默认情况下,MSS为536字节。这个数字是从哪里来的呢?

  • IP的默认最大传输单元(MTU)为576字节。超过此大小的任何内容都将被拆分。
  • IP头占用20字节。
  • TCP头占用20字节。

因此,536 = 576 - 20 - 20。

你可以看出MSS仅表示数据体的大小,不包括头部。

1*creWLybyfKDBJgTzQP1kDg.png

MSS是在TCP三次握手期间进行协商的。以下是TCP段头的格式。MSS位于TCP选项中。

1*pQpFRUuyzaG4JOm93Wg5Zw.png

在SYN消息中,客户端建议MSS为1460字节。这被称为发送方最大段大小(SMSS)。

1*dG1cCAjKY0v8Xfx2SeBcFA.png

在服务器的响应中,它建议段的大小不超过1400字节。由于大小来自服务器,因此被称为接收方最大段大小(RMSS)。

TCP 重传

为了确保传输的可靠性,TCP需要完成两个功能:

  • 当接收到消息时,接收方向发送方发送确认(ACK)。
  • 当消息丢失时,发送方重新传输消息。

让我们从一个简单的模型开始。

1*bvkdWnFF55OCLfstaE_GEw.png

1.首先,发送方在发送消息后维护一个计时器。2.在时间过期之前收到第一个ACK。然后,计时器被重置以等待第二条消息,然后重复此过程。3.第二个计时器过期,没有收到ACK。重传开始。

这种简单的设计是直接的,但效率较低,因为每个消息都需要等待前一个ACK返回。

让我们改进一下。

1*suv0nuvpmgUWaTd6riMUsQ.png

通过为每条消息分配一个ID,我们可以迅速发送多条消息。相同的ID与相应的计时器和ACK消息相链接。

如果一条消息丢失,例如#3,发送方将重新传输它。

在TCP中,“消息ID”是什么?它是序列号。

1*EbU2NjtCGn8z4gVCJr2Tyg.png

这里是一个消息的示例:

  • 此TCP段的长度为647字节。
  • 在此消息之前,发送方已经发送了1461字节。
  • 发送方将从2108开始发送更多字节。

序列号最多可以达到2³²。然后它会重新开始。

这带来了一个问题。

1*RLp9kmWuRzlgY-NQs2F4Hw.png

想象一下,我们只有4个序列号,每次发送1字节。

  • 在过程中,第2个字节(标记为#2)丢失。根据设计,#2将在以后的时间重新传输。
  • 我们继续发送更多字节,直到序列号从#1开始。此时,重新传输的#2被发送。
  • 接收方不知道这是旧的#2还是新的#2。这可能会搞乱事情。

为了解决这个问题,TCP选项中引入了时间戳。

1*jSrwaU0L-2EHyyIxzb2w_A.png

时间戳可以消除具有相同序列号的段之间的歧义。

让我们将时间戳附加到每个段上。

接收方读取时间戳B并将其与先前的时间戳E进行比较,以确认这是一次重传。否则,时间戳应该大于E。

TCP快速重传

TCP具有快速重传功能 - 在计时器到期之前重新传输丢失的段。

为了允许快速重传,我们需要为发送方和接收方设置一些规则。

  • 规则1:作为接收方,它应始终发送它期望接收的序列号。例如,当接收方接收到段1时,它将响应ACK2,表示它期望在即将到来的消息中接收段2。
  • 规则2:作为发送方,它应忽略计时器并在接收到3个重复的乱序ACK后立即开始重新传输丢失的段。

1*nbAE5D9yMkUxvxxR4PJ27g.png

上图显示了快速重传的示例:

  • 在第一个2个段的传输之后,段3丢失。
  • 在接收到段4时,接收方根据规则发送ACK3,而不是ACK4。这是第一个重复的乱序ACK。
  • 再次,在接收到段5时,服务器仍然期望重新传输段3。因此,第二个重复的ACK3被发送。
  • 然后,第三个重复的ACK3被发送。
  • 在这一刻,发送方进入快速重传并重新传输段3。6.在接收到丢失的段后,接收方的ACK按顺序返回,并期望在即将到来的消息中接收段7。
  • 但是存在一个问题 - 发送方不知道段5和段6是否安全到达,直到快速重传完成。如果两个段都丢失,那么后续的重传将需要更长的时间。

接收方可以通过选择性确认(SACK)功能与发送方共享信息,以便促进重传过程。

TCP选择性确认

1*GhT0tOhF3YGrgQOIY56Esw.png

SACK位于TCP选项中。

在SACK中,我们可以指定已经接收到的数据的范围,超过确认号。

1*LujjJhnNyITz1dyL-CFfbA.png

这是SACK的示例,表示已接收的数据范围从2872到3393。

有了它,发送方知道不需要重新传输这些边界之间的任何字节。

此外,发送方还可以找出其他丢失的段并尽快进行重传。

总结

  • 最大段大小(MSS)定义了TCP段的长度。
  • 计时器帮助TCP重新传输丢失的段。
  • 在收到3个重复的ACK后,快速重传在计时器到期之前开始。
  • 选择性确认(SACK)提供有关已接收的乱序字节的信息,以促进快速重传过程。
责任编辑:赵宁宁 来源: 小技术君
相关推荐

2021-05-27 10:57:01

TCP定时器网络协议

2010-06-28 15:41:04

FTP文件传输协议

2019-12-13 10:50:10

TCP排查服务器

2021-05-18 09:12:40

TCP网络分层网络协议

2020-07-10 09:04:55

HTTPS浏览器网络协议

2023-11-10 16:28:02

TCP窗口

2020-04-10 08:55:26

TCPIPBBR算法

2009-03-09 09:24:00

无线网络传输无线信号

2010-08-27 09:45:49

CSS Sprites

2009-06-05 11:01:23

struts mvcMVC工作原理

2010-09-07 13:04:14

CSS Hack

2011-12-20 15:52:03

PhoneGap架构基础工作原理

2011-12-07 14:25:33

JavaNIO

2009-02-18 09:42:58

TCPISO传输

2021-07-27 05:13:12

TCPUDP 拥塞

2011-07-01 10:07:22

VAAIVMware vSto

2009-06-04 10:41:52

Struts工作原理

2012-04-18 16:42:03

PhoneGap

2018-06-29 23:21:27

物联网IoT网络

2013-11-19 09:53:17

点赞
收藏

51CTO技术栈公众号