一般来说都是通过iperf来测试网络带宽,然而我对iperf的工作原理一直持怀疑态度,怎么可能在短时间内通过发送大量的数据包填满链路,从而得出网络的带宽呢。

考虑到传送文件才具有真正的意义,所以产生了通过nc(netcat)来测试网络带宽的想法,然而通过测试,验证了一个我之前的错误想法:iperf的确可以测试到真正的网络带宽,nc也可以,然而受到的制约因素较多,不适合用于纯粹的网络带宽测试。

网络拓扑如下:

hostA<---> switch <---> hostB

1. iperf

  • hostA

    $ sudo iperf -s
  • hostB

    $ sudo iperf -c A.ip
    $ sudo iftop -n -i eth0

通过iftop可以看到iperf的确在短时间内发送了大量的数据包去塞满整个网卡,1G的网卡的带宽可达941Mbits

2. nc

  • hostA

    $ sudo nc -v -n -l 2222 > /dev/null
  • hostB

    $ sudo pv /dev/zero | nc <hostA-ip> 2222
nc测速截图

不同的A和不同的B,不同的nc/dd,即便使用的都是千兆网卡,测试的结果千差万别,受到A的写速度、B的读速度和网络环境三个因素的影响。

可能的原因是:netcat似乎不支持TCP Windowing,它每发送一个数据包都需要获得ack后方进行下一步,而iperf可以一次性发送多个数据包,获得一个ack后再进一步发送,所以iperf可以测试到网络的吞吐量。

以下是nc的规律:

	1. Packet ->
	2. <- Ack
	3. Packet ->
	4. <- Ack
	5. Packet ->
	6. <- Ack
	7. Packet ->
	8. <- Ack

以下是iperf的规律:

	1. Packet ->
	2. Packet ->
	3. Packet ->
	4. Packet ->
	5. Packet ->
	6. Packet ->
	7. <- Ack
	8. Packet ->
	9. Packet ->
	10. Packet ->
	11. Packet ->
	12. Packet ->
	13. Packet ->
	14. <- Ack
	15. Packet ->
	16. Packet ->
	17. Packet ->
	18. Packet ->
	19. Packet ->
	20. Packet ->
	21. <- Ack

详细说明详见该链接

所以说,iperf仍然是测试网络带宽的金标准。

吞吐量跟网络带宽是两回事。