使用英语阅读

通过


Windows TCP 功能的说明

本文介绍 Windows 中的 TCP 功能。

原始 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
说明:通知其他主机允许选择性 Ack。

种类: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]) 段本身的 Window 字段永远不会缩放。

这意味着在三向握手后发送的第一个数据包是实际窗口大小。 如果有缩放因子,则始终使用 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

例如:

如果注册表中的窗口大小以小数形式输入为 26900000000(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. 在“新建值”框中,键入 Tcp1323OptsEnter,然后在 “编辑” 菜单上选择“ 修改”。

    备注

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

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

时间戳

以前,TCP/IP 堆栈为每个发送的数据窗口使用了一个样本来计算往返时间(RTT)。 发送数据包时设置了计时器(重新传输计时器),直到收到确认为止。 例如,如果以太网网络上的窗口大小为 64,240 字节(44 个完整段),则每 44 个数据包中只有一个用于重新计算往返时间。 最大窗口大小为 65,535 字节,此采样率就足够了。 使用窗口缩放,最大窗口大小为 1 千兆字节,此 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 位,这会限制可用的序列号数。 使用高容量网络和大型数据传输,可以在数据包遍历网络之前包装序列号。 如果在每秒一千兆字节(Gbps)网络上发送数据,序列号可以包装在短短的 34 秒内。 如果数据包延迟,则可能存在具有相同序列号的其他数据包。 为了避免混淆重复的序列号,TCP 时间戳用作序列号的扩展。 数据包具有当前时间戳和正在进行的时间戳。 旧数据包具有较旧的时间戳,并被丢弃。

选择性确认 (SDK)

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

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

TCP Sack 允许的选项仅用于 SYN 数据包(在 TCP 连接建立期间),以指示它可以执行选择性 ACK。

第二个 TCP 选项“TCP Sack 选项”包含一个或多个数据块的确认。 数据块是在开始和结束数据块时使用序列号标识的。 它也称为数据块的左边缘和右边缘。

类型 4 是 TCP 允许的选项。 类型 5 是 TCP 解雇选项。 长度是此 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 数,以重新发送传输中已删除的段。