如何解释这个令人难以置信的慢插座连接?

时间:2012-04-30 03:04:36

标签: windows performance tcp winsock

我试图在两台PC之间设置带宽测试,它们之间只有一个切换。所有网络硬件都是千兆位。一台机器我把一个程序打开一个套接字,监听连接,接受,然后循环读取数据并测量接收到的“性能计数器”字节。在另一台机器上,程序打开一个插座,连接到第一台机器,然后进入紧密循环,以便尽可能快地将数据泵入连接,每个send()调用1K块。只需这样设置,事情似乎快得可笑;我可以通过网络获得大约30到40个 MBytes /秒 - 明显快于100BaseT,在千兆位h / w的合理范围内。

以下是乐趣的开始:我尝试使用setsockopt()将每端的缓冲区大小(SO_SNDBUF,SO_RCVBUF)设置为1K。突然,接收端报告它每秒仅获得4,000或5,000字节。检测事物的发送方面,似乎send()调用每个需要0.2到0.3秒,只发送1K块。从接收端删除setsockopt()似乎没有改变。

现在显然,试图操纵缓冲区大小是一个坏主意。我原以为可能强制缓冲区大小为1K,send()调用为1K,这将是一种强制操作系统在每次发送调用时将一个数据包放在线路上的方法,同时理解这会阻止网络堆栈有效地组合数据进行传输 - 但我没想到吞吐量会下降到4-5K /秒!

我没有时间在资源上追逐这个并且真正理解我想要的方式,但是我真的想知道什么可以让send()花费0.2秒。即使它正在等待来自另一方的ack,0.2秒也难以置信。是什么给了什么?

2 个答案:

答案 0 :(得分:3)

解释只是1k缓冲区是一个令人难以置信的缓冲区大小,你的发送机器可能一次发送一个数据包。在清空缓冲区并接受从应用程序发送的下一个块之前,发送方必须等待来自接收方的确认(因为TCP层可能需要稍后重新传输数据)。

一个更有趣的练习是将缓冲区大小从系统的默认值(查询它以查找它是什么)一直变为1k,并查看每个缓冲区大小如何影响您的吞吐量。

答案 1 :(得分:3)