Windows TCP 功能说明

本文介绍 Windows 中的 TCP 功能。

适用于:Windows 10 - 所有版本,Windows Server 2012 R2
原始 KB 编号: 224829

摘要

本文介绍 Windows 中的以下 TCP 功能:

  • TCP 窗口大小
  • 现在支持 TCP 选项
  • Windows 缩放 - RFC 1323
  • 时间戳 - RFC 1323
  • 防止包装序列号 (PAWS)
  • 选择性确认 (SACKS) - RFC 2018
  • TCP 重新传输行为和快速重新传输

可以通过更改注册表中的条目来更改 TCP 功能。

重要

以下部分、方法或任务包含有关如何修改注册表的步骤。 但是,注册表修改不当可能会出现严重问题。 因此,请务必严格按照这些步骤操作。 为了加强保护,应先备份注册表,再进行修改。 如果出现问题,可以还原注册表。 有关如何备份和还原注册表的更多信息,请单击下面的文章编号查看 Microsoft 知识库中相应的文章:
322756 如何在 Windows 中备份和还原注册表

TCP 窗口大小

TCP 接收窗口大小是在连接期间可以缓冲的) 接收数据 ((以字节为单位)。 发送主机在必须等待接收主机的确认和窗口更新之前,只能发送该量的数据。 Windows TCP/IP 堆栈设计为在大多数环境中自行优化,并使用比早期版本更大的默认窗口大小。

TCP 不使用硬编码的默认接收窗口大小,而是调整为 MSS) (最大段大小的增量。 MSS 是在连接设置过程中协商的。 将接收窗口调整为 MSS 的增量会增加在批量数据传输期间使用的全尺寸 TCP 段的百分比。

接收窗口大小按以下方式确定:

  1. 发送到远程主机的第一个连接请求) 播发 16K (16,384 字节的接收窗口大小。
  2. 建立连接后,接收窗口大小将向上舍入为 MSS 的偶数增量。
  3. 窗口大小调整为 MSS 的四倍,最大大小为 64 K,除非使用 (RFC 1323) 的窗口缩放选项。

注意

请参阅“Windows 缩放”部分。

对于以太网连接,窗口大小通常设置为 17,520 字节, (16K 舍入到 12 个 1460 字节段) 。 与支持扩展 TCP 头选项的计算机建立连接时,窗口大小可能会减小,例如选择性确认 (SACKS) 和时间戳。 这两个选项将 TCP 标头大小增加到 20 个以上的字节,这会导致数据空间减少。

在早期版本的 Windows NT中,以太网连接的窗口大小为 8,760 字节,即 6 个 1460 字节段。

若要将接收窗口大小设置为特定值,请将 TcpWindowSize 值添加到特定于 Windows 版本的注册表子项。 为此,请执行以下步骤:

  1. 选择“ 开始>运行”,键入 Regedit,然后选择“ 确定”。

  2. 展开特定于 Windows 版本的注册表子项:

    • 对于 Windows 2000,展开以下子项: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces

    • 对于 Windows Server 2003,展开以下子项: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  3. “编辑” 菜单上,指向“ 新建”,然后选择“ DWORD 值”。

  4. TcpWindowSize在“新建值”框中键入,然后按 Enter

  5. “编辑”菜单上选择“修改”。

  6. 在“ 值数据 ”框中键入所需的窗口大小。

    注意

    窗口大小的有效范围为 0-0x3FFFC000 十六进制。

默认情况下,此值不存在。 添加 TcpWindowSize 值时,它会替代上面讨论的默认窗口大小算法。

注意

还可以将 TcpWindowSize 添加到 Parameters 键,以全局设置所有接口的窗口大小。

现在支持 TCP 选项

以前,TCP 选项主要用于协商最大段大小。 在 Windows 中,TCP 选项用于窗口缩放、时间戳和选择性 ACK。

有两种类型的 TCP 选项:

  1. 单个八进制 TCP 选项,用于指示特定的选项类型。
  2. 多八进制 TCP 选项,它由选项类型、选项长度和一系列选项八位组组成。

以下列表显示了每种 TCP 选项类型、长度、名称和说明。

种类:0
长度:1
选项:选项列表的末尾
说明:在最后一个 TCP 选项需要填充时使用。

种类:1
长度:1
选项:无操作
说明:在需要填充时使用,并且在同一数据包中遵循更多 TCP 选项时使用。

种类:2
长度:4
选项:最大段大小
说明:指示可以通过网络发送的 TCP 段的最大大小。

种类:3
长度:3
选项:窗口缩放选项
说明:标识使用大于 64k 的窗口时要使用的缩放因子。

类型:8
长度:10
选项:时间戳选项
说明:用于帮助计算传输的数据包的往返时间 (RTT) 。

种类:4
长度:2
选项:允许 TCP SACK
说明:通知其他主机允许选择性确认。

类型:5
长度:变化
选项:TCP SACK 选项
说明:主机用于确定是否收到了无序数据包。

Windows 缩放

为了更有效地使用高带宽网络,可以使用更大的 TCP 窗口大小。 TCP 窗口大小字段控制数据流,限制为 2 个字节,或 65,535 字节的窗口大小。

由于无法扩展大小字段,因此使用缩放因子。 TCP 窗口缩放是用于将最大窗口大小从 65,535 字节增加到 1 GB 的选项。

窗口缩放选项仅在 TCP 三向握手期间使用。 窗口缩放值表示向左移动 16 位窗口大小字段的位数。 窗口缩放值可以从 0 (无班次) 设置为 14。

若要计算真正的窗口大小,请将窗口大小乘以 2^S,其中 S 是小数位数值。

例如:

如果窗口大小为 65,535 字节,窗口缩放因子为 3。
True 窗口大小 = 65535*2^3

True 窗口大小 = 524280

以下网络监视器跟踪演示如何使用窗口缩放选项:

TCP: ....S., len:0, seq:725163-725163, ack:0, win:65535, src:1217 dst:139(NBT Session)  
TCP: Source Port = 0x04C1  
TCP: Destination Port = NETBIOS Session Service  
TCP: Sequence Number = 725163 (0xB10AB)  
TCP: Acknowledgement Number = 0 (0x0)  
TCP: Data Offset = 44 (0x2C)  
TCP: Reserved = 0 (0x0000)  
+ TCP: Flags = 0x02 : ....S.  
TCP: Window = 65535 (0xFFFF)  
TCP: Checksum = 0x8565  
TCP: Urgent Pointer = 0 (0x0)  
TCP: Options  
+ TCP: Maximum Segment Size Option  
TCP: Option Nop = 1 (0x1)  
TCP: Window Scale Option  
TCP: Option Type = Window Scale  
TCP: Option Length = 3 (0x3)  
TCP: Window Scale = 3 (0x3)  
TCP: Option Nop = 1 (0x1)  
TCP: Option Nop = 1 (0x1)  
+ TCP: Timestamps Option  
TCP: Option Nop = 1 (0x1)  
TCP: Option Nop = 1 (0x1)  
+ TCP: SACK Permitted Option  

实际三向握手中使用的窗口大小不是按 RFC 1323 第 2.2 节缩放的窗口大小:

“SYN 中的窗口字段 (例如,[SYN] 或 [SYN,ACK] ) 段本身永远不会缩放。”

这意味着在三向握手后发送的第一个数据包是实际的窗口大小。 如果有缩放因子,则始终使用初始窗口大小 65,535 字节。 然后,窗口大小乘以在三向握手中标识的缩放因子。 下表显示了各种窗口大小的缩放因子边界。

比例因子 缩放值 初始窗口 窗口缩放
0 1 65535 或更低 65535 或更低
1 2 65535 131,070
2 4 65535 262,140
3 8 65535 524,280
4 16 65535 1,048,560
5 32 65535 2,097,120
6 64 65535 4,194,240
7 128 65535 8,388,480
8 256 65535 16,776,960
9 512 65535 33,553,920
10 1024 65535 67,107,840
11 2048 65535 134,215,680
12 4096 65535 268,431,360
13 8192 65535 536,862,720
14 16384 65535 1,073,725,440

例如:

如果注册表中的窗口大小输入为 269000000 (269M) 十进制,则三向握手期间的缩放因子为 13。 缩放因子 12 仅允许窗口大小高达 268,431,360 字节 (268M) 。

此示例中的初始窗口大小计算如下:
65,535 字节,窗口缩放因子为 13。
True 窗口大小 = 65535*2^13
True 窗口大小 = 536,862,720

当窗口大小的值添加到注册表中,并且其大小大于默认值时,Windows 会尝试使用适应新窗口大小的缩放值。

可以添加以下注册表项中的 Tcp1323Opts 值,以控制缩放窗口和时间戳:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters

  1. 在工具栏上,选择“开始>运行”,然后键入Regedit启动注册表编辑器。

  2. 在“注册表编辑器,选择”编辑“,指向”新建“,然后选择”DWORD 值”。

  3. 在“新建值”框中,键入 Tcp1323Opts,按 Enter,然后在 “编辑 ”菜单上,选择“ 修改”。

    注意

    有效范围为 0、1、2 或 3,其中:
    0 (禁用 RFC 1323 选项)
    1 (窗口缩放仅启用)
    2 (时间戳仅启用)
    3 (启用这两个选项)

此注册表项控制 RFC 1323 时间戳和窗口缩放选项。 时间戳和窗口缩放默认启用,但可以使用标志位进行操作。 位 0 控制窗口缩放。 位 1 控制时间戳。

时间 戳

以前,TCP/IP 堆栈为每个发送的数据窗口使用一个样本来计算 RTT) (往返时间。 在发送数据包时设置计时器 (重新传输计时器) ,直到收到确认。 例如,如果窗口大小为 64,240 字节 (以太网网络上) 的 44 个完整段,则每 44 个数据包中只有一个用于重新计算往返时间。 最大窗口大小为 65,535 字节时,此采样率就足够了。 使用窗口缩放,最大窗口大小为 1 GB,此 RTT 采样率是不够的。

TCP 时间戳选项现在可用于堆栈认为适当的段 (数据和 ACK) ,以执行如下操作:

  • RTT 计算
  • PAWS 检查

使用此数据,可以准确计算大窗口大小的 RTT。 RTT 用于计算重新传输间隔。 为了获得最佳吞吐量,需要准确的 RTT 和重新传输超时。

在 TCP 会话中使用 TCP 时间戳时,会话的发起方在其 TCP 三向握手的第一个数据包中发送选项, (SYN 数据包) 。 然后,任一端都可以在会话期间使用 TCP 选项。

TCP 时间戳选项 (TSopt) :

Kind = 8 长度 = 10 TS 值 (Tsval) TS 回显回复 (Tsecr)
1 个字节 1 个字节 4 字节 4 字节

可以通过展开 TCP 选项字段在网络监视器跟踪中查看时间戳选项字段,如下所示:

TCP: Timestamps Option  
TCP: Option Type = Timestamps  
TCP: Option Length = 10 (0xA)  
TCP: Timestamp = 2525186 (0x268802)  
TCP: Reply Timestamp = 1823192 (0x1BD1D8)

防止包装序列号 (PAWS)

TCP 序列号字段限制为 32 位,这限制了可用的序列号数。 对于高容量网络和大型数据传输,可以在数据包遍历网络之前包装序列号。 如果以每秒 1 千兆字节 (Gbps) 网络发送数据,则序列号可以在 34 秒内换行。 如果数据包延迟,则可能存在具有相同序列号的不同数据包。 为了避免混淆重复序列号,TCP 时间戳用作序列号的扩展。 数据包具有当前时间戳和正在进行的时间戳。 旧数据包具有较旧的时间戳,并且会被丢弃。

选择性确认 (SDK)

Windows 引入了对称为选择性确认或 SACK 的性能功能的支持。 SACK 对于使用大型 TCP 窗口大小的连接尤其重要。 在 SACK 之前,接收方只能确认已接收的连续数据流的最新序列号或接收窗口的“左边缘”。 启用 SACK 后,接收方将继续使用 ACK 编号来确认接收窗口的左边缘,但它也可以单独确认其他已接收数据块。 SACK 使用 TCP 标头选项,如下所示。

SACK 使用两种类型的 TCP 选项。

TCP Sack-Permitted 选项仅在建立 TCP 连接期间在 SYN 数据包 (中使用,) 指示它可以执行选择性 ACK。

第二个 TCP 选项 TCP Sack 选项包含一个或多个数据块的确认。 数据块在数据块的开头和末尾使用序列号进行标识。 它也称为数据块的左边缘和右边缘。

类型 4 是 TCP Sack-Permitted 选项。 类型 5 为 TCP 麻袋选项。 Length 是此 TCP 选项的长度(以字节为单位)。

允许的 Tcp SACK:

Kind = 4 长度 = 2
1 个字节 1 个字节

Tcp SACK 选项:

Kind = 5 Length = Variable
1 个字节 第一个块的左边缘到第一个块的右边缘
...
第 N 个块的左边缘到第 N 个块的右边缘

启用 SACK (默认) 后,可以丢弃数据包或一系列数据包。 接收方通知发送方已收到哪些数据,以及数据中可能存在“漏洞” 的位置。 然后,发送方可以选择性地重新传输缺失的数据,而无需重新传输已成功接收的数据块。 SACK 由 SackOpts 注册表参数控制。

可以编辑以下注册表项中的 SackOpts 值以控制选择性确认的使用:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  1. 在工具栏上,选择“开始>运行”,然后键入Regedit启动注册表编辑器。
  2. 在“注册表”编辑器中找到并选择上述项,然后在“编辑”菜单中选择“修改”。
  3. 在“ 值数据 ”框中键入所需的值。

注意

有效的二进制值为 0 或 1,默认值为 1。 此参数控制是否启用了选择性 ACK (SACK - RFC 2018) 支持。

以下网络监视器跟踪演示了主机确认序列号54857341的所有数据,以及序列号 54858789-54861685 中的数据。 缺少的数据从54857341到54858788。

TCP: .A...., len:0, seq:925104-925104, ack:54857341, win:32722, src:1242 dst:139  
TCP: Source Port = 0x04DA  
TCP: Destination Port = NETBIOS Session Service  
TCP: Sequence Number = 925104 (0xE1DB0)  
TCP: Acknowledgement Number = 54857341 (0x3450E7D)  
TCP: Data Offset = 44 (0x2C)  
TCP: Reserved = 0 (0x0000)  
+ TCP: Flags = 0x10 : .A....  
TCP: Window = 32722 (0x7FD2)  
TCP: Checksum = 0x4A72  
TCP: Urgent Pointer = 0 (0x0)  
TCP: Options  
TCP: Option Nop = 1 (0x1)  
TCP: Option Nop = 1 (0x1)  
+ TCP: Timestamps Option  
TCP: Option Nop = 1 (0x1)  
TCP: Option Nop = 1 (0x1)  
TCP: SACK Option  
TCP: Option Type = 0x05  
TCP: Option Length = 10 (0xA)  
TCP: Left Edge of Block = 54858789 (0x3451425)  
TCP: Right Edge of Block = 54861685 (0x3451F75)

TCP 重新传输行为和快速重新传输

TCP 重新传输

作为对正常重新传输行为的评审,当每个出站段下发到 Internet 协议 (IP) 时,TCP 会启动重新传输计时器。 如果在计时器过期之前未收到给定段中数据的确认,则会重新传输该段。

RTO) (重新传输超时会持续调整,以使用平滑往返时间 (SRTT) 计算来匹配连接的特征,如 RFC 793 中所述。 给定段的计时器在每次重新传输该段后翻倍。 使用此算法时,TCP 会自行调整为连接的正常延迟。

快速重新传输

在某些情况下,TCP 会在重新传输计时器过期之前重新传输数据。 最常见的原因是称为快速重新传输的功能。 当支持快速重新传输的接收器接收序列号超过当前预期序列号的数据时,可能会删除某些数据。 为了帮助通知发送方此事件,接收方立即发送 ACK,并将 ACK 编号设置为预期的序列号。 它将继续对到达的每个额外的 TCP 段执行此操作。 当发送方开始接收确认相同序列号的 ACK 流时,段可能已被删除。 发送方将立即重新发送接收方预期的段,而无需等待重新传输计时器过期。 当数据包频繁丢弃时,此优化可显著提高性能。

默认情况下,Windows 在以下条件下重新发送段:

  • 它接收同一序列号的三个 ACK:一个 ACK 和两个重复项。
  • 序列号滞后当前序列号。

此行为是可以使用注册表参数控制的 TcpMaxDupAcks

可以编辑以下注册表项中的 TcpMaxDupAcks 值,以控制启动快速重新传输所需的 ACK 数:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters

  1. 在工具栏上,选择“开始>运行”,然后键入Regedit启动注册表编辑器。
  2. 在“注册表”编辑器中找到并选择上述项,然后在“编辑”菜单中选择“修改”。
  3. 在“ 值数据 ”框中键入所需的值。

注意

有效范围为 1-3,默认值为 2。

此参数确定在触发以重新发送传输中已删除的段之前 fast retransmit ,必须接收相同序列号的重复 ACK 数。