【发布时间】:2012-04-23 23:18:09
【问题描述】:
我试图了解接收器窗口如何影响高延迟连接的吞吐量。
我在相距很远的两台机器上有一对简单的客户端-服务器应用程序,两者之间的连接为 250 毫秒延迟 RTT。我在 Windows(XP,7)和 Linux(Ubuntu 10.x)上运行了这个测试,结果相同,所以为简单起见,我们假设以下情况: 客户端接收数据:WinXP Pro 服务器发送数据:Win7 Pro 同样,延迟为 250 毫秒 RTT。
我在不更改客户端上的接收器缓冲区大小的情况下运行 TCP 测试(默认为 8Kb),我在线上看到(使用 Wireshark):
- 客户端向服务器发送ACKS并且TCP数据包包含RWIN=65k
- 服务器发送数据并报告 RWIN=65k
查看跟踪我看到了 3-4 个数据包的突发(有效负载为 1460 字节),紧接着是从客户端机器发送到服务器的 ACK,然后在大约 250 毫秒内什么都没有,然后是一个新的数据包突发从服务器到客户端。
因此,总而言之,服务器似乎在填满接收器窗口之前也没有发送新数据。
为了做更多的测试,这次我也运行了相同的测试,在客户端机器上更改接收器的缓冲区大小(在 Windows 上,更改接收器的缓冲区大小最终会影响机器通告的 RWIN)。我希望在阻塞 ACK 之前看到大量的数据包......并且至少有更高的吞吐量。
在这种情况下,我将 recv 缓冲区大小设置为 100,000,000。从客户端到服务器的数据包现在有一个 RWIN=99,999,744(嗯,这很好),但不幸的是,从服务器发送到客户端的数据模式仍然是相同的:短暂的突发,然后是长时间的等待。 为了确认我在网络上看到的内容,我还测量了从服务器向客户端发送大量数据的时间。我没有看到使用大 RWIN 或使用默认值的任何变化。
谁能帮我理解为什么更改 RWIN 并不会真正影响吞吐量?
几点注意事项: - 服务器使用 8Kb 块的 write() 尽可能快地发送数据 - 正如我之前所说,我在使用 Linux 时也看到了类似的效果。更改接收缓冲区大小会影响节点使用的 RWIN,但吞吐量保持不变。 - 我分析了几百包后的trace,给TCP慢启动机制足够的时间来扩大CWIN大小。
按照建议,我在此处添加了线迹的小快照
No. Time Source Destination Protocol Length Info
21 2.005080 CCC.CCC.CCC.CCC sss.sss.sss.sss TCP 60 57353 > 21500 [ACK] Seq=1 Ack=11681 Win=99999744 Len=0
22 2.005109 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=19305 Ack=1 Win=65536 Len=1460
23 2.005116 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=20765 Ack=1 Win=65536 Len=1460
24 2.005121 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=22225 Ack=1 Win=65536 Len=1460
25 2.005128 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 946 21500 > 57353 [PSH, ACK] Seq=23685 Ack=1 Win=65536 Len=892
26 2.005154 CCC.CCC.CCC.CCC sss.sss.sss.sss TCP 60 57353 > 21500 [ACK] Seq=1 Ack=14601 Win=99999744 Len=0
27 2.007106 CCC.CCC.CCC.CCC sss.sss.sss.sss TCP 60 57353 > 21500 [ACK] Seq=1 Ack=16385 Win=99999744 Len=0
28 2.007398 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=24577 Ack=1 Win=65536 Len=1460
29 2.007401 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=26037 Ack=1 Win=65536 Len=1460
30 2.007403 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=27497 Ack=1 Win=65536 Len=1460
31 2.007404 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=28957 Ack=1 Win=65536 Len=1460
32 2.007406 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=30417 Ack=1 Win=65536 Len=1460
33 2.007408 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 946 21500 > 57353 [PSH, ACK] Seq=31877 Ack=1 Win=65536 Len=892
34 2.007883 CCC.CCC.CCC.CCC sss.sss.sss.sss TCP 60 57353 > 21500 [ACK] Seq=1 Ack=19305 Win=99999744 Len=0
35 2.257143 CCC.CCC.CCC.CCC sss.sss.sss.sss TCP 60 57353 > 21500 [ACK] Seq=1 Ack=22225 Win=99999744 Len=0
36 2.257160 CCC.CCC.CCC.CCC sss.sss.sss.sss TCP 60 57353 > 21500 [ACK] Seq=1 Ack=24577 Win=99999744 Len=0
37 2.257358 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=32769 Ack=1 Win=65536 Len=1460
38 2.257362 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=34229 Ack=1 Win=65536 Len=1460
39 2.257364 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=35689 Ack=1 Win=65536 Len=1460
40 2.257365 sss.sss.sss.sss CCC.CCC.CCC.CCC TCP 1514 21500 > 57353 [ACK] Seq=37149 Ack=1 Win=65536 Len=1460
如您所见,服务器在数据包 #33 处停止发送数据。
客户端在旧数据包的数据包 #34 处发送 ACK(seq=19305,在数据包 #20 上发送,此处未显示)。 使用 100Mb 的 RWIN,我希望服务器不会阻塞一段时间。
在 20-30 个数据包之后,服务器端的拥塞窗口应该足够大,可以发送比我看到的更多的数据包...... 我假设拥塞窗口最终会增长到 RWIN...但是,即使在数百个数据包之后,模式仍然是相同的:数据数据然后阻塞 250 毫秒...
【问题讨论】:
-
两台机器都是无线的吗?您能否在数据包和确认中打印从服务器/客户端发送回来和第四次发送的序列号。客户端或服务器端可能存在大量噪音,导致数据丢失。
标签: performance networking tcp latency throughput