首页 > 代码库 > Iperf软件介绍
Iperf软件介绍
Iperf 版本建议采用linux版本,事实上,windows版也很好用。Iperf 是一个 TCP/IP 和 UDP/IP 的性能测量工具,通过调谐各种参数可以测试TCP的最大带宽,并报告带宽、延迟,最大段和最大传输单元大小等统计信息。Iperf可以运行于Linux/BSD、Unix及Windows等操作系统。
带宽测试通常采用UDP模式,因为能测出极限带宽、时延抖动、丢包率。在进行测试时,首先以链路理论带宽作为数据发送速率进行测试,例如,从客户端到服务器之间的链路的理论带宽为100Mbps,先用 -b 100M进行测试,然后根据测试结果(包括实际带宽,时延抖动和丢包率),再以实际带宽作为数据发送速率进行测试,会发现时延抖动和丢包率比第一次好很多,重复测试几次,就能得出稳定的实际带宽。
1、UDP 模式
服务器端 iperf -u -s
客户端
iperf -u -c 192.168.1.1 -b 100M -t 60
在udp模式下,以100Mbps为数据发送速率,客户端到服务器192.168.1.1上传带宽测试,测试时间为60秒。
iperf -u -c 192.168.1.1 -b 5M -P 30 -t 60
客户端同时向服务器端发起30个连接线程,以5Mbps为数据发送速率。
iperf -u -c 192.168.1.1 -b 100M -d -t 60
以100M为数据发送速率,进行上下行带宽测试。
2、TCP模式
服务器端 iperf -s
客户端
iperf -c 192.168.1.1 -t 60
在tcp模式下,客户端到服务器192.168.1.1上传带宽测试,测试时间为60秒。
iperf -c 192.168.1.1 -P 30 -t 60
客户端同时向服务器端发起30个连接线程。
iperf -c 192.168.1.1 -d -t 60
进行上下行带宽测试。
另外,
-p 监听或者连接的端口号
-w TCP滑动窗口的大小
3、Iperf工作原理
Iperf主要的功能是测试基于特定路径的TCP连接的性能,我们知道TCP连接调整最基本的措施是调整TCP窗口的大小,窗口大小控制在任何节点网络中可以存在的数据大小。如果该值太小,发送者将会在某段时间处于空闲状态,从而影响发送的性能。TCP窗口大小的理论值为链路瓶颈带宽与往返时延的乘积:
TCP_Window=Bottleneck_Bandwidth*Round_Trip_Time
例如链路瓶颈带宽为45Mbps,往返时延为42ms(可以通过ping来测试),那么窗口的理论值为:
45Mbps*42ms=(45*e6)*(42*e-3)=1890000 bits=230KByte
调节窗口大小即可以理论值为基准,在该值上慢慢增大或减少,即可获得最好的结果。
Iperf测试TCP带宽的原理较简单,即在客户端和服务器端建立连接(三次握手)后,客户端发送一定大小的数据报,并记下发送的时间, 或者客户端在一定的时间内发送数据,并记下发送的总数据。带宽的大小等于发送的总数据除以发送的总时间。对服务器端来说,就是在连接建立时间内,接收的总数据除以所花时间即为服务器端所测得的带宽。MSS的大小通过TCP内核接口函数直接获得。
Iperf测试UDP的性能时,客户端可以指定UDP数据流的速率。客户端发送数据时,将根据客户提供的速率计算数据报发送之间的时延。另外客户还可以指定发送数据报的大小。每个发送的数据报包含一个ID号,用来惟一地标识该报文。服务器端则根据该ID号来确定数据报丢失和乱序。当把UDP报文大小设置可以将整个报文放入IP层的包(packet)内时,那么UDP所测得的报文丢失数据即为IP层包的丢失数据。这提供了一个有效的测试包丢失情况的方法。数据报传输延迟抖动 (Jitter)的测试由服务器端完成,客户发送的报文数据包含有发送时间戳,服务器端根据该时间信息和接收到报文的时间戳来计算传输延迟抖动。传输延迟抖动反映传输过程中是否平滑。由于它是一个相对值,所以并不需要客户端和服务器端时间同步。
4、Iperf实现
Iperf源代码采用面向对象的C++语言实现,主要包括基本类和实现类两部分。基本类提供了实现中需要用到的一些基本的对象,包括队列、链表、时间管理、锁、条件、线程等,这些代码不是特定于Iperf应用的,可以移植到其他应用程序。实现类中主要包括针对Iperf应用的类,包括实现客户端/服务器端发送和接收数据的类,以及用于统计信息的类等。这里主要讨论一下与应用关系最紧密的几个类,其他的类不做详述(转载者注:后面转载文章有讲解)。
Iperf主要类图结构包括9个类。Iperf 的核心部分均在PerfSocket类中实现,包括客户端和服务器端发送和接收数据、带宽报告、数据丢失及延迟抖动报告,以及窗口大小和MSS报告等功能。其中Speaker和Client为客户端的对象,Listener、Audience和Server为服务器端的对象。客户端和服务器端的通信通过三个消息完成:connect、write以及shutdown。这里connect不同于TCP中的连接,它还包含一个数据报文,其信息为双向测试而传给服务器端 的信息,主要用于双向测试时让服务器端启动客户端线程而所需要的信息。UDP 测试的过程基本上跟TCP类似。UDP报文包含了一个应用报文头,其主要字段为报文ID和时间信息,这个主要是为了测试UDP报文的丢失、乱序以及延迟抖动性能。UDP的第一个报文用来建立连接,不作为应用数据,其信息为双向测试而传给服务器端的信息,主要用于双向测试时让服务器端启动客户端线程而所需要的信息。UDP与TCP第一个报文内容的主要区别是UDP报文还包括一个应用报文头。UDP传输结束通过客户端发送一个FIN的报文来实现,该报文的报文ID为负数,服务器端接收到FIN报文后即停止接收报文并回送一个 AckFIN报文给客户,AckFIN报文包含了服务器端得到的测试数据。
操作举例:
1)TCP测试
服务器执行:iperf -s -i 1 -w 1M
客户端执行:iperf -c host -i 1 -w 1M
其中-w表示TCP window size,host需替换成服务器地址。
2)UDP测试
服务器执行:iperf -u -s
客户端执行:iperf -u -c 10.32.0.254 -b 900M -i 1 -w 1M -t 60
其中-b表示使用带宽数量,千兆链路使用90%容量进行测试就可以了。
5、Iperf提供的库
在开发Iperf的过程中,开发者把 Socket编程和多线程编程中经常用到的一些系统调用封装成对象,屏蔽了底层函数的复杂接口,提供了模块化和面向对象的机制,也为我们提供了一些非常实用的编程工具,我们可以在实现自己的程序时复用这些类。由于这些类实现的源代码都比较简单,也为我们修改前人的代码实现自己的功能提供了方便。
这些类的定义与实现都在源代码文件夹的lib子文件夹下。主要包括以下一些对象:
SocketAddr类:封装了Socket接口中的网络地址结构(sockaddr_in等)以及各种地址转换的系统调用(gethostbyname、gethostbyaddr、inet_ntop等);
Socket类:封装了socket文件描述符,以及socket、listen、connect等系统调用;
Mutex类以及Condition类:封装了POSIX标准中的mutex和condition(条件变量)线程同步机制;
Thread类:封装了POSIX标准中的多线程机制,提供了一种简单易用的线程模型;
Timestamp类:通过Unix系统调用gettimeofday实现了一个时间戳对象,提供了获得当前时间戳,计算两个时间戳之间的先后关系等方法。
此外,在lib文件夹中还包括一些Iperf的实现提供的实用工具函数,包括endian.c文件中的字节序转换函数、gnu_getopt文件中的命令行参数处理函数、snprintf文件中的字符串格式化函数、signal.c文件中的与信号处理有关的函数、 string.c文件中的字符处理函数、tcp_window_size.c文件中的TCP窗口大小处理函数等。