Windows TCP窗口缩放过早达到高原


50

场景:我们有许多Windows客户端定期将大文件(FTP / SVN / HTTP PUT / SCP)上传到距离服务器100-160毫秒的Linux服务器。我们办公室的同步带宽为1Gbit / s,服务器是AWS实例或物理托管在美国DC中。

最初的报告是,上传到新服务器实例的速度要慢得多。这在测试中和从多个位置产生出来;客户端从Windows系统向主机看到稳定的2-5Mbit / s。

iperf -s在一个AWS实例上爆发,然后从办公室的Windows客户端爆发:

iperf -c 1.2.3.4

[  5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55185
[  5]  0.0-10.0 sec  6.55 MBytes  5.48 Mbits/sec

iperf -w1M -c 1.2.3.4

[  4] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 55239
[  4]  0.0-18.3 sec   196 MBytes  89.6 Mbits/sec

后面的数字在后续测试中可能会发生很大变化(AWS的变化),但通常在70到130Mbit / s之间,足以满足我们的需求。窃听会话,我可以看到:

  • iperf -c Windows SYN-Window 64kb,Scale 1-Linux SYN,ACK:Window 14kb,Scale:9(* 512) 使用默认的64kb窗口缩放iperf窗口
  • iperf -c -w1M Windows SYN-Windows 64kb,Scale 1-Linux SYN,ACK:Window 14kb,Scale:9 iperf窗口缩放,默认为1MB窗口

显然,链接可以维持这种高吞吐量,但是我必须明确设置窗口大小以使用它,大多数现实世界的应用程序都不允许我这样做。在每种情况下,TCP握手使用相同的起点,但是强制缩放

相反,从同一网络上的Linux客户端,直接iperf -c使用系统默认值85kb可以得到:

[  5] local 10.169.40.14 port 5001 connected with 1.2.3.4 port 33263
[  5]  0.0-10.8 sec   142 MBytes   110 Mbits/sec

在没有任何强制的情况下,它可以按预期扩展。这不可能是中间的跃点或本地交换机/路由器中的东西,并且似乎会影响Windows 7和8客户端。我已经阅读了许多有关自动调整的指南,但是这些指南通常是关于完全禁用扩展以解决糟糕的家庭网络套件问题。

谁能告诉我这里发生了什么,并给我一种解决方法?(最好是可以通过GPO坚持注册的内容。)

笔记

有问题的AWS Linux实例在以下方面应用了以下内核设置sysctl.conf

net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.rmem_default = 1048576
net.core.wmem_default = 1048576
net.ipv4.tcp_rmem = 4096 1048576 16777216
net.ipv4.tcp_wmem = 4096 1048576 16777216

我已经在服务器端使用dd if=/dev/zero | nc重定向/dev/null到来排除iperf并消除任何其他可能的瓶颈,但是结果却几乎相同。使用ncftp(Cygwin,Native Windows,Linux)进行测试的规模与上述在各自平台上进行的iperf测试大致相同。

编辑

我在这里发现了可能与之相关的另一件事: 在此处输入图片说明

这是1MB捕获的第一秒钟,放大了。随着窗口的扩大和缓冲区变大,您可以看到Slow Start的动作。有那么〜0.2s的这个小平台正是在默认窗口iperf的测试拉平永远的地步。这当然可以缩放到很多眩晕的高度,但是很好奇在缩放之前会有这种暂停(值是1022bytes * 512 = 523264)。

更新-6月30日。

跟进各种回应:

  • 启用CTCP-这没有区别;窗口缩放是相同的。(如果我理解正确,此设置将增加拥塞窗口的放大率,而不是它可以达到的最大大小)
  • 启用TCP时间戳。-这里也没有变化。
  • Nagle的算法-很有道理,至少这意味着我可以忽略图中的特定斑点作为问题的任何迹象。
  • pcap文件:可在此处找到的Zip文件:https : //www.dropbox.com/s/104qdysmk01lnf6/iperf-pcaps-10s-Win%2BLinux-2014-06-30.zip每个OS客户端一个供比较)

更新2-6月30日

哦,所以按照关于Kyle建议的操作,我启用了ctcp并禁用了烟囱卸载:TCP全局参数

----------------------------------------------
Receive-Side Scaling State          : enabled
Chimney Offload State               : disabled
NetDMA State                        : enabled
Direct Cache Acess (DCA)            : disabled
Receive Window Auto-Tuning Level    : normal
Add-On Congestion Control Provider  : ctcp
ECN Capability                      : disabled
RFC 1323 Timestamps                 : enabled
Initial RTO                         : 3000
Non Sack Rtt Resiliency             : disabled

但是可悲的是,吞吐量没有变化。

我在这里确实有一个因果问题:图形是在服务器到客户端的ACK中设置的RWIN值。对于Windows客户端,我是否认为Linux不会将这个值扩展到这个最低点以上,因为客户端有限的CWIN甚至无法填充该缓冲区吗?Linux是否会人为限制RWIN的其他原因?

注意:我已经尝试过为它打开ECN。但是没有变化。

更新3-6月31日。

禁用启发式和RWIN自动调整后没有任何变化。已使用通过设备管理器选项卡公开功能调整的软件,已将英特尔网络驱动程序更新至最新版本(12.10.28.0)。该卡是82579V芯片组板载NIC-(我将从Realtek或其他供应商的客户那里进行更多测试)

专注于NIC片刻,我尝试了以下操作(大多数情况下只是排除了不太可能的罪魁祸首):

  • 将接收缓冲区从256增加到2k,将发送缓冲区从512增加到2k(现在都最大)-不变
  • 禁用所有IP / TCP / UDP校验和卸载。- 没变。
  • 禁用大型发送卸载-Nada。
  • 关闭IPv6,QoS调度-Nowt。

更新3-7月3日

为了消除Linux服务器端,我启动了Server 2012R2实例,并使用iperf(cygwin二进制)和NTttcp重复了测试。

有了iperf,我必须明确指定-w1m两个双方之前的连接将扩展到超过〜5Mbit / s的。(顺便说一句,我可以检查一下,在91ms延迟下〜5Mbits的BDP几乎恰好是64kb。找出限制...)

ntttcp二进制文件现在显示了这种限制。通过ntttcpr -m 1,0,1.2.3.5在服务器和ntttcp -s -m 1,0,1.2.3.5 -t 10客户端上使用,我可以看到更好的吞吐量:

Copyright Version 5.28
Network activity progressing...


Thread  Time(s) Throughput(KB/s) Avg B / Compl
======  ======= ================ =============
     0    9.990         8155.355     65536.000

#####  Totals:  #####

   Bytes(MEG)    realtime(s) Avg Frame Size Throughput(MB/s)
================ =========== ============== ================
       79.562500      10.001       1442.556            7.955

Throughput(Buffers/s) Cycles/Byte       Buffers
===================== =========== =============
              127.287     308.256      1273.000

DPCs(count/s) Pkts(num/DPC)   Intr(count/s) Pkts(num/intr)
============= ============= =============== ==============
     1868.713         0.785        9336.366          0.157

Packets Sent Packets Received Retransmits Errors Avg. CPU %
============ ================ =========== ====== ==========
       57833            14664           0      0      9.476

8MB / s达到了我在中显式使用大窗口所获得的水平iperf。不过,奇怪的是,在1273个缓冲区中有80MB =再次是64kB缓冲区。进一步的Wireshark显示了一个很好的,可变的RWIN从服务器返回(客户端似乎已实现)(比例因子256);因此,ntttcp可能会误报发送窗口。

更新4-7月3日

在@karyhead的要求下,我进行了一些测试,并生成了一些更多的捕获信息,请访问:https ://www.dropbox.com/s/dtlvy1vi46x75it/iperf%2Bntttcp%2Bftp-pcaps-2014-07-03.zip

  • iperf从Windows到与以前的相同(1.2.3.4)相同的Linux服务器,还有另外两个s:一个具有128k套接字大小和默认的64k窗口(再次限制为〜5Mbit / s),另一个具有1MB的发送窗口和默认的8kb套接字尺寸。(比例更高)
  • ntttcp从同一Windows客户端到Server 2012R2 EC2实例(1.2.3.5)的一条跟踪。在这里,吞吐量可以很好地扩展。注意:NTttcp在打开测试连接之前会对端口6001做一些奇怪的事情。不知道那里发生了什么。
  • 一个FTP数据跟踪,/dev/urandom使用Cygwin 将20MB的数据上传到几乎相同的linux主机(1.2.3.6)ncftp。再次有极限。使用Windows Filezilla时,模式几乎相同。

更改iperf缓冲区长度确实会与时序图(更多的垂直部分)产生预期的差异,但实际吞吐量没有变化。


11
经过充分研究的问题的罕见情况,在文档中并未明确提及。很好-我们希望有人能找到解决方案(因为我认为我也可以使用该解决方案)。
TomTom 2014年

2
尝试打开RFC 1323时间戳记,因为Windows默认情况下将其禁用,而Linux默认情况下将其启用)。netsh int tcp set global timestamps=enabled
Brian

3
200 ms的延迟可能是Nagle算法在起作用。由于TCP在特定连接上接收到数据,因此只有在满足以下条件之一的情况下,它才发送回确认:对于先前收到的段,没有发送确认;接收到一个段,但是没有其他段在200毫秒内到达该连接。
Greg Askew 2014年

2
是否有可能从某个较慢的发件人某处捕获某些数据包?
凯尔·布​​兰特

我已经用这些测试的结果以及指向代表性捕获文件的链接更新了OP。
SmallClanger 2014年

Answers:


15

您是否尝试过在Windows 7/8客户端中启用复合TCP(CTCP)。

请阅读:

提高高BDP传输的发送方性能

http://technet.microsoft.com/zh-cn/magazine/2007.01.cableguy.aspx

...

这些算法适用于较小的BDP和较小的接收窗口大小。但是,当您的TCP连接具有较大的接收窗口大小和较大的BDP时,例如在往返时间跨度为100ms的高速WAN链接上的两台服务器之间复制数据,这些算法不会增加发送窗口足够快以充分利用连接带宽

为了在这些情况下更好地利用TCP连接的带宽,下一代TCP / IP堆栈包括复合TCP(CTCP)。对于 具有较大接收窗口大小和BDP的连接,CTCP会更积极地增加发送窗口。CTCP试图通过监视延迟变化和损失来最大化这些类型的连接的吞吐量。另外,CTCP确保其行为不会对其他TCP连接产生负面影响。

...

默认情况下,在运行Windows Server 2008的计算机中启用CTCP,并在运行Windows Vista的计算机中默认禁用。您可以使用以下netsh interface tcp set global congestionprovider=ctcp命令启用CTCP 。您可以使用该netsh interface tcp set global congestionprovider=none命令禁用CTCP 。

编辑6/30/2014

看看CTCP是否真的“打开”

> netsh int tcp show global

在此处输入图片说明

PO说:

如果我正确理解此设置,则此设置将增加 拥塞窗口的放大率,而不是 其可以达到的最大大小

CTCP积极增加发送窗口

http://technet.microsoft.com/zh-CN/library/bb878127.aspx

复合TCP

防止发送方TCP对等点淹没网络的现有算法称为缓慢启动和拥塞避免。当最初在连接上发送数据以及从丢失的段中恢复时,这些算法会增加发送方可以发送的段的数量(称为发送窗口)。对于接收到的每个确认段(对于Windows XP和Windows Server 2003,对于TCP)或对于每个确认的段(对于Windows Vista和Windows Server 2008,对于TCP),慢速启动将发送窗口增加一个完整的TCP段。对于每个已确认的完整数据窗口,拥塞避免可将发送窗口增加一个完整TCP段。

这些算法适用于LAN媒体速度和较小的TCP窗口大小。但是,当您的TCP连接具有较大的接收窗口大小和较大的带宽延迟乘积(高带宽和高延迟)时,例如在往返于高速WAN链接的两台服务器之间复制数据(往返行程为100毫秒)时间,这些算法没有足够快地增加发送窗口以充分利用连接的带宽。例如,在具有100 ms往返时间(RTT)的每秒1 Gb(Gbps)的WAN链路上,发送窗口最初增加到接收器和接收者所通告大窗口大小可能 需要一个小时。 在丢失段时恢复

为了在这些情况下更好地利用 TCP连接的带宽,下一代TCP / IP堆栈包括复合TCP (CTCP)。对于具有大接收窗口大小和大带宽延迟乘积的连接,CTCP更加积极地增加了发送窗口。CTCP试图通过监视延迟变化和损失来最大化这些类型的连接的吞吐量。CTCP还确保其行为不会对其他TCP连接产生负面影响。

在Microsoft内部进行的测试中,对于具有50ms RTT的1 Gbps连接,大文件备份时间减少了近一半。具有较大带宽延迟积的连接可以具有更好的性能。CTCP和“接收窗口自动调整”共同工作,可以提高链路利用率,并且可以为大量的带宽延迟产品连接带来显着的性能提升。


3
作为对此答案的补充,Server 2012 / Win8.1中的Powershell等效项Set-NetTCPSetting带有-CongestionProvider参数...,该参数接受CCTP,DCTCP和默认值。Windows客户端和服务器使用不同的默认拥塞提供程序。technet.microsoft.com/zh-CN/library/hh826132.aspx
Ryan Ries

我了解您的意思,但这似乎并不适用。为了这个目的,我跑了30分钟iperf,而Window仍然没有扩展到超过520kb。在此激进算法无法显示任何益处之前,还有其他一些限制CWND的方法。
SmallClanger

有一个旧的(已经修复)的Vista错误,在传输非HTML协议时会出现这种问题。通过HTML或通过FTP传输相同文件时,您的问题看起来是否完全相同?
2014年

@Pat-是的。SVN提交(通过HTTP和HTTPS)和FTP到AWS上另一个系统的传输也具有相同的限制。
SmallClanger 2014年

Win客户端的防火墙怎么样?您可以在防火墙完全关闭的情况下进行测试吗?在这里看到:ask.wireshark.org/questions/2365/tcp-window-size-and-scaling
帕特

12

澄清问题:

TCP有两个窗口:

  • 接收窗口:缓冲区中剩余多少字节。这是接收器施加的流量控制。您可以在wireshark中看到接收窗口的大小,因为它由TCP报头中的窗口大小和窗口缩放比例组成。TCP连接的两端都将通告其接收窗口,但是通常您关心的是接收大量数据的那一侧。在您的情况下,它是“服务器”,因为客户端正在上载到服务器
  • 拥塞窗口。这是发件人施加的流量控制。这是由操作系统维护的,不会显示在TCP标头中。它控制数据发送速度。

在您提供的捕获文件中。我们可以看到接收缓冲区永远不会溢出:

在此处输入图片说明

我的分析是,由于发送窗口(即拥塞控制窗口)打开的速度不足以满足接收者的RWIN,因此发送者的发送速度不够快。简而言之,接收方说“给我更多”,而当Windows作为发送方时,它的发送速度不够快。

这可以通过以下事实得到证明:在上图中,RWIN保持打开状态,往返时间为.09秒,RWIN为〜500,000字节,根据带宽延迟乘积,我们可以预期最大吞吐量为(500000 /0.09)* 8 =〜42 Mbit / s(在Linux捕获中,您的获利仅为〜5)。

如何解决?

我不知道。interface tcp set global congestionprovider=ctcp听起来对我来说是正确的事,因为这会增加发送窗口(这是拥塞窗口的另一个术语)。您说那没用。因此,请确保:

  1. 启用此功能后是否重新启动?
  2. 烟囱卸载了吗?如果可能,请尝试将其关闭作为实验。我不知道启用此功能时到底卸载了什么,但是如果控制发送窗口是其中之一,那么启用此功能时,congestionprovider可能没有任何作用...我只是在猜测...
  3. 另外,我认为这可能是Windows 7之前的版本,但是您可以尝试在HKEY_LOCAL_MACHINE-System-CurrentControlSet-Services-AFD-Parameters中添加并使用名为DefaultSendWindow和DefaultReceiveWindow的两个注册表项。如果这些方法都起作用,您可能希望关闭ctcp。
  4. 还有另一种猜测,请尝试检查netsh interface tcp show heuristics。我认为这可能是RWIN,但没有说明,因此可能要禁用/启用该功能,以防它影响发送窗口。
  5. 另外,请确保您的驱动程序在测试客户端上是最新的。也许有些东西坏了。

我将从所有卸载功能开始尝试所有这些实验,以消除网络驱动程序进行某些重写/修改(禁用卸载时保持CPU注意力)的可能性。该TCP_OFFLOAD_STATE_DELEGATED结构似乎至少暗示的CWnd卸载至少是可能的。


2
我已经报告了您的“答案”,因为您的答案不是答案;我立刻被否决了。现在我怎么看“人”是最新的投票你的“无应答” ......真的很有趣
帕特

1
@帕特:您也可以单击投票号,以查看支持者/支持者的细目分类。目前,您的答案还没有否决票。我的答案不能解决他的问题(但还没有答案),它确实可以解释和定位问题(希望正确!),这是解决问题的重要步骤。
凯尔·布​​兰特

@凯尔·勃兰特(Kyle Brandt)如果您接受您的问题,那不是答案,我想知道为什么没有进一步考虑就不能“自动”删除它?你错了;当我报告您的“答案”时,我“马上”投票(取消投票);一个尚未被删除。看来您在这里遵循“特殊”规则。
专利

1
@Pat如果有帮助,Kyle的非回答功能非常有用。现在,我对限制哪些缓冲区有了一个更清晰的了解,因此,我觉得自己离适当的解决方案还差一点。有时问题,比如这可能是一个合作努力的是,有位明智的编辑可以成为一个适当的Q和合适的一个
SmallClanger 2014年

@SmallClanger在所有应有的尊重下,SF拥有一套规则,包括Kyle Brandt在内的所有用户都应遵循;如果他的答案不是答案,则无论“主持人”俱乐部中有多少朋友,都必须将其删除或移动为评论。
2014年

5

@Pat和@Kyle在这里提供了一些很棒的信息。一定要注意@Kyle 对TCP接收和发送窗口的解释,我认为对此有些困惑。为了进一步混淆问题,iperf使用术语“ TCP窗口”和-w设置,该设置对于接收,发送或整体滑动窗口来说是一个模棱两可的术语。它实际上所做的是为-c(客户端)实例设置套接字发送缓冲区,为(服务器)实例设置套接字接收缓冲区-s。在src/tcp_window_size.c

if ( !inSend ) {
    /* receive buffer -- set
     * note: results are verified after connect() or listen(),
     * since some OS's don't show the corrected value until then. */
    newTCPWin = inTCPWin;
    rc = setsockopt( inSock, SOL_SOCKET, SO_RCVBUF,
                     (char*) &newTCPWin, sizeof( newTCPWin ));
} else {
    /* send buffer -- set
     * note: results are verified after connect() or listen(),
     * since some OS's don't show the corrected value until then. */
    newTCPWin = inTCPWin;
    rc = setsockopt( inSock, SOL_SOCKET, SO_SNDBUF,
                     (char*) &newTCPWin, sizeof( newTCPWin ));
}

正如Kyle提到的那样,问题不在于Linux盒上的接收窗口,而是发送者没有充分打开发送窗口。这并不是说打开速度不够快,它的上限仅为64k。

Windows 7上的默认套接字缓冲区大小为64k。这是文档中有关MSDN上套接字缓冲区大小与吞吐量的关系的说明

使用Windows套接字通过TCP连接发送数据时,重要的是要在TCP中保留足够数量的未完成数据(已发送但尚未确认),以实现最高吞吐量。为实现TCP连接的最佳吞吐量而需要处理的未完成数据量的理想值称为理想发送积压(ISB)大小。ISB值是TCP连接的带宽延迟乘积与接收者的广告接收窗口(部分是网络中的拥塞量)的函数。

好吧,等等等等,现在我们开始:

一次执行一个阻止或非阻止发送请求的应用程序通常依靠Winsock的内部发送缓冲来获得不错的吞吐量。给定连接的发送缓冲区限制由SO_SNDBUF套接字选项控制。对于阻塞式和非阻塞式发送方法,发送缓冲区限制决定了TCP中有多少未完成的数据。如果连接的ISB值大于发送缓冲区限制,则连接上实现的吞吐量将不是最佳的。

使用64k窗口进行的最新iperf测试的平均吞吐量为5.8Mbps。那是来自Wireshark中的Statistics> Summary,它计算所有位。iperf可能会计算5.7Mbps的TCP数据吞吐量。我们在FTP测试中也看到了相同的性能,约为5.6Mbps。

具有64k发送缓冲区和91ms RTT的理论吞吐量为.... 5.5Mbps。对我来说足够接近。

如果我们查看您的1MB窗口iperf测试,则输出速率为88.2Mbps(仅TCP数据为86.2Mbps)。窗口为1MB时的理论吞吐量为87.9Mbps。再次,足够接近政府工作。

这表明发送套接字缓冲区直接控制发送窗口,并与另一端的接收窗口一起控制吞吐量。广告接收窗口有空间,因此我们不受接收者的限制。

等等,这个自动调整业务如何?Windows 7不会自动处理这些东西吗?如前所述,Windows确实可以处理接收窗口的自动缩放,但是它也可以动态地处理发送缓冲区。让我们回到MSDN页面:

Windows 7和Windows Server 2008 R2上增加了TCP的动态发送缓冲。默认情况下,除非应用程序在流套接字上设置SO_SNDBUF套接字选项,否则将启用TCP的动态发送缓冲。

iperf SO_SNDBUF在使用该-w选项时使用,因此将禁用动态发送缓冲。但是,如果您不使用,-w则它不会使用SO_SNDBUF。默认情况下,动态发送缓冲应该处于打开状态,但是您可以检查:

netsh winsock show autotuning

该文档说您可以通过以下方式禁用它:

netsh winsock set autotuning off

但这对我没有用。我必须更改注册表并将其设置为0:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AFD\Parameters\DynamicSendBufferDisable

我认为禁用此功能不会有所帮助;仅供参考。

当将数据发送到接收窗口中有足够空间的Linux盒时,为什么发送缓冲区的缩放比例不能超过默认的64k?好问题。Linux内核也具有自动调整TCP堆栈。就像T-Pain和Kanye一起进行自动调谐二重奏一样,这听起来可能并不好。这两个自动调整TCP堆栈相互通信可能存在一些问题。

另一个人遇到了和您一样的问题,并可以通过注册表编辑来解决此问题,以增加默认的发送缓冲区大小。不幸的是,这似乎不再起作用了,至少当我尝试时它对我来说没有用。

在这一点上,我认为很明显限制因素是Windows主机上的发送缓冲区大小。鉴于它似乎不能动态地正常生长,一个女孩该怎么办?

您可以:

  • 使用允许您设置发送缓冲区即窗口选项的应用程序
  • 使用本地Linux代理
  • 使用远程Windows代理?
  • 与Microsofhahahahahahaha一起开箱
  • 啤酒

免责声明:我花了很多时间研究这个问题,据我所知和google-fu,这是正确的。但是我不会在母亲的坟墓上发誓(她还活着)。


奇妙的输入;谢谢。我正在使用iperf 2.0.4,我将尝试设置并使用一些新的上限来更新我的OP。
SmallClanger 2014年

好的,我已经根据更多的研究和您最近的测试更新了我的“答案”
karyhead 2014年

谢谢。至少在某种程度上,很高兴知道我不仅在生气。我从XP / 2003时代读过一些推荐这些注册表设置的博客/主题,但是它们是在Vista / 2008之前编写的,我很确定它们会在Vista以后被忽略。我想,我居然会提高一票与MS这个(祝我好运)
SmallClanger

1
我在研究中遇到的有用工具是SDK中的tcpanalyzer.exe(microsoft.com/en-us/download/details.aspx?id=8279)。这是一个图形化的netstat,您可以选择单个连接并获取TCP统计信息,例如RTT,cwnd,重传等。我可以使cwnd大大超出发送缓冲区的大小,但是tput并没有增加,并且wireshark已验证它仍然发送缓冲区有限。
karyhead 2014年

1
我在几个论坛上发现有关“ netsh”命令无法按7/8中的说明运行的评论,人们被迫手动输入相应的注册表项;我想知道CTCP选项是否会发生这种情况。
专利

4

调整好TCP堆栈后,Winsock层可能仍然存在瓶颈。我发现在Windows 7中配置Winsock(注册表中的辅助功能驱动程序)对上载速度(将数据推送到服务器)有很大的不同。浏览器使用的一种套接字;-)

为DefaultSendWindow添加DWORD密钥,并将其设置为BDP或更高版本。我正在使用256000。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\AFD\Parameters\DefaultSendWindow

更改Winsock的下载设置可能会有所帮助-为DefaultReceiveWindow添加一个密钥。

您可以使用Fiddler代理和命令来调整客户端和服务器套接字缓冲区的大小,以尝试各种套接字级别设置:

prefs set fiddler.network.sockets.Server_SO_SNDBUF 65536 

fiddler.network.sockets.Client_SO_SNDBUF
fiddler.network.sockets.Client_SO_RCVBUF
fiddler.network.sockets.Server_SO_SNDBUF
fiddler.network.sockets.Server_SO_RCVBUF

大量附加信息。您是否有MS Bug的参考链接?
SmallClanger 2015年

3

阅读了答案中的所有分析后,此问题听起来很像是您可能在运行Windows7 / 2008R2,也就是Windows 6.1

Windows 6.1中的网络堆栈(TCP / IP和Winsock)存在严重缺陷,并且存在大量错误和性能问题,自6.1最初发布以来,Microsoft多年来一直在解决这些错误,并最终解决了许多年。

应用这些修补程序的最佳方法是手动浏览support.microsoft.com上的所有相关页面,并手动请求和下载网络堆栈修补程序的LDR版本(其中有数十种)。

要查找相关的修补程序,必须将www.bing.com与以下搜索查询一起使用 site:support.microsoft.com 6.1.7601 tcpip.sys

您还需要了解LDR / GDR修补程序训练如何在Windows 6.1中工作

通常,我通常会维护自己的Windows 6.1 LDR修复程序列表(而不仅仅是网络堆栈修复程序),然后将这些修复程序主动地应用于遇到的任何Windows 6.1服务器/客户端。定期检查新的LDR修补程序是一项非常耗时的任务。

幸运的是,Microsoft停止了使用较新的OS版本的LDR修复程序的实践,并且现在可以通过Microsoft的自动更新服务获得错误修复程序。

更新:Windows 7SP1中许多网络错误的一个示例-https: //support.microsoft.com/en-us/kb/2675785

更新2:这是另一个修补程序,它添加了一个netsh开关,以在第二次重新发送SYN数据包后强制窗口缩放(默认情况下,在重新发送2个SYN数据包之后,窗口缩放被禁用)https://support.microsoft.com/zh-cn我们/ kb / 2780879


谢谢克里斯托夫;关于此的一些非常有趣的新输入,并且SYN重传“功能”非常奇怪;我根本看不到其背后的设计目标。(也许是某种粗略的拥塞检测?)。所有原始测试都是在Win7SP1上完成的。我们将很快试用Win10,请我重新运行其中的大部分内容,以查看其效果如何。
SmallClanger

您将使用Windows 10的哪个分支进行测试?我对Windows 10中的网络堆栈没有任何经验。
Christoph Wegener

企业1511是我们的目标。
SmallClanger

我懂了。由于Windows 10有很多分支,因此很难决定要使用Windows 10的分支。我已经遇到了Windows 10的一个问题,因为我在LTSB分支上,因此无法使用特定功能。我想微软已经总体上降低了可用的分支的数量,而是提高了他们什么修复和功能都包含在每一个构建文档....
克里斯托夫·韦格纳

1

我看到这是一个较旧的帖子,但可以帮助其他人。

简而言之,您必须启用“接收窗口自动调整”:

netsh int tcp set global autotuninglevel=normal

如果未启用上述功能,则CTCP无效。

如果禁用“接收窗口自动调整”,则将被固定在64KB的数据包大小上,这会对高宽带连接中的长RTT产生负面影响。您也可以尝试使用“受限”和“高度受限”选项。

很好的参考:https : //www.duckware.com/blog/how-windows-is-killing-internet-download-speeds/index.html


1

Windows客户端(Windows 7)遇到了类似的问题。我经历了大多数调试过程,禁用了Nagle算法,TCP烟囱卸载功能以及其他与TCP相关的其他设置更改。它们都不起作用。

最终为我解决的问题是修改AFD服务注册表中的默认发送窗口。该问题似乎与afd.sys文件有关。我测试了几个客户端,有些客户端的上传速度很慢,有些客户端没有,但是都是Windows 7计算机。表现出较慢行为的计算机具有相同版本的AFD.sys。对于具有某些AFD.sys版本的计算机,注册表解决方法是必需的(对不起,请不要撤回版本号)。

HKLM \ CurrentControlSet \ Services \ AFD \ Parameters

添加-DWORD-DefaultSendWindow

值-十进制-1640960

这个价值是我在这里找到的: https //helpdesk.egnyte.com/hc/en-us/articles/201638254-Upload-Speed-Slow-over-WebDAV-Windows-

我认为要使用适当的值,您应该使用以下方法自己计算:

例如。广告上传:15 Mbps = 15,000 Kbps

(15000/8)* 1024 = 1920000

据我了解,客户端软件通常应在注册表中覆盖此设置,但如果不这样做,则使用默认值,并且在某些版本的AFD.sys文件中,默认值显然很低。

我注意到大多数MS产品的上传速度都很慢(IE,小型重定向器(WebDAV),通过Windows资源管理器的FTP等)。使用3rd party软件(例如Filezilla)时,我没有同样的速度降低问题。

AFD.sys影响所有Winsock连接,因此此修复程序应适用于FTP,HTTP,HTTPS等。

另外,此修复程序也在上面的某个位置列出,因此,如果它对任何人都有效,我也不会因此而功劳,但是此线程中有太多信息,我担心它可能会被掩盖。


0

好吧,我本人也遇到了类似的情况(这里是我的问题),最后我不得不禁用TCP扩展试探法,手动设置自动调整配置文件并启用CTCP:

# disable heuristics
C:\Windows\system32>netsh interface tcp set heuristics wsh=disabled
Ok.

# enable receive-side scaling
C:\Windows\system32>netsh int tcp set global rss=enabled
Ok.

# manually set autotuning profile
C:\Windows\system32>netsh interface tcp set global autotuning=experimental
Ok. 

# set congestion provider
C:\Windows\system32>netsh interface tcp set global congestionprovider=ctcp
Ok. 

0

我没有足够的意见要发表,所以我将发布一个“答案”。我遇到了类似/相同的问题(请参阅此处的 serverfault问题)。我(可能是您)的问题是Windows上iperf客户端的发送缓冲区。它不会超过64 KB。如果进程未明确指定缓冲区的大小,则Windows应该动态增加缓冲区。但是这种动态增长并未发生。

我不确定您的窗口缩放图是否显示“慢速” Windows情况下窗口最多打开500,000字节。考虑到您的速度限制为5 Mbps,我希望看到该图只能打开〜64,000字节。


0

这是一个令人着迷的线程,与我使用Win7 / iperf来测试长胖管道上的吞吐量时遇到的问题完全匹配。

Windows 7的解决方案是在iperf服务器和客户端上执行以下命令。

netsh接口tcp设置全局autotuninglevel =实验

注意:在执行此操作之前,请确保记录自动调整的当前状态:

netsh接口tcp显示全局

接收窗口自动调整级别:已禁用

然后在管道的每一端运行iperf服务器/客户端。

在测试后重置自动调整值:

netsh接口tcp设置全局autotuninglevel =

   autotuninglevel - One of the following values:
                     disabled: Fix the receive window at its default
                         value.
                     highlyrestricted: Allow the receive window to
                         grow beyond its default value, but do so
                         very conservatively.
                     restricted: Allow the receive window to grow
                         beyond its default value, but limit such
                         growth in some scenarios.
                     normal: Allow the receive window to grow to
                         accomodate almost all scenarios.
                     experimental: Allow the receive window to grow
                         to accomodate extreme scenarios.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.