IPerf——网络测试工具介绍与源码解析(2)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介:

对于IPerf源码解析,我是基于2.0.5版本在Windows下执行的情况进行分析的,提倡开始先通过对源码的简单修改使其能够在本地编译器运行起来,这样可以打印输出一些中间信息,对于理解源码的逻辑,程序实现的过程能够起到事半功倍的效果。

IPerf主要分为如下几个模块:

  • 选项参数处理;
  • 线程封装和角色扮演;
    • 四种线程模式(或者说角色):
      • 客户端线程;
      • 服务端线程;
      • 报告者线程;
      • 监听者线程。
  • 套接字选项设置与提取;
  • 链表和数组的封装和维护;
  • 处理多并发Condition条件变量的封装;
  • 时间戳封装;
  • Windows下作为后台服务运行的创建和运行。

下面尽可能针对每个模块进行说明:

选项参数的处理:

作为命令行控制台应用程序,首要考虑到的问题就是对输入参数命令行选项的处理,如果是简单的应用程序直接通过case-switch或者if条件语句或许可以解决,但是一旦到了规模较大,实现内容较为复杂的控制台应用程序,比如IPerf,还是用该处理方法就显得相对笨拙,在性能、逻辑处理等方面都有所不及。

对于选项参数的处理,IPerf使用的GUN的一个getopt文件,在Linux下已有该头文件,而在Windows需要自己导入该头文件和实现文件,加入文件之后,还需要做的就是对文件中的一些长选项和短选项字符串进行处理,因为这是自己定义的需求,处理选项参数的逻辑是一定的,但是要将哪些内容作为合理的选项和参数以及操作数,那些又是非法的字符和未能识别的操作数,程序需要据此进行判断,所以需要进行一个初始化的过程,后面在使用的过程中调用相应的接口对主函数传进来的args和argv[]作为输入参数进行处理就行了,更多关于选项参数的处理,可以看看该篇文章,或者自行网上找寻。

 

程序的主要模块就是角色线程的生成、运行和销毁,其他模块包括时间戳、条件变量、维护的链表等都是为此服务的,所以这里打算先说一下其他模块然后在逐一分析不同类型的线程。

 

套接字选项的封装和设置:

说套接字选项之前还需要先说一下套接字的生成,IPerf对套接字Socket的生成定义了一个名为WIN32Socket的宏,这个宏内部调用了WSASocket,而套接字的属性和协议类型是通过定义WSAPROTOCOL_INFO类型静态函数,并将该函数作为输入参数传到WASSocket实现的。

PerfSocket.cpp中只有一个名为SetSocketOptions的函数,顾名思义就是用来设置套接字选项的值,函数里面包含设置TCP滑动窗口大小(setsock_tcp_windowsize函数在另一个名为tcp_window_size.c的文件中单独实现)、设置拥塞控制、设置多播、设置IP服务类型(这个很少用得到)、设置最大报文段大小(setsock_tcp_mss函数在sockets.c文件中实现)、设置非延迟等。当然,除了设置套接字选项外,也有获取相应选项的函数,比如getsock_tcp_windowsize和getsock_tcp_mss。

在SocketAddr.c文件中,IPerf定义了一系列以“SocketAddr_函数功能”格式命名的函数,通过宏条件判断是否支持IPV6,定义了包括:通过IP地址获取到或者说转换成对端的套接字地址结构,将网络序转成点分十进制,获取和设置端口值等,围绕着定义的iperf_sockaddr类型(IPV4下为sockaddr_in类型,IPV6下为sockaddr_storage)判断该套接字地址是否相同等。

 

链表和数组的维护和封装:

IPerf在实现中创建了几种不同类型的链表和数组:在开始时的线程链表,报告使用的报告者首部链表,监听(者)线程维护的客户端链表,紧接在传送类型报告者首部后面的包数组,在服务端和多并发客户端维护的多组报告首部维护的传输信息数组。具体的接下来会详细讲述到,List.cpp封装对Iperf_ListEntry类型链表的增删查和销毁操作,而该链表仅是监听者用来存储和维护已连接客户端的信息,别无它用。

 

处理多并发Condition条件变量的封装:

Condition是IPerf自己封装的结构体,变量mCondition为事件内核对象的句柄,变量mMutex为互斥量的句柄,

Condition_Initialize( Cond ): 创建一个初始化就处于触发状态的互斥量并把返回的句柄值赋予mMutex,创建一个初始化为未触发状态的手动重置事件并把返回的句柄值赋予mCondition;

Condition_Destroy( Cond ):通过mCondition和mMutex的句柄值销毁事件内核对象和互斥量;

Condition_Lock( Cond )  == Mutex_Lock( &Cond.mMutex ) == WaitForSingleObject( Cond.mMutex, INFINITE )

Condition_Unlock( Cond ) == Mutex_Unlock( &Cond.mMutex ) == ReleaseMutex( Cond.mMutex )

Condition_Wait( Cond ): 首先释放互斥量,接着阻塞永久等待事件发生,然后等待互斥量;

Condition_TimedWait( Cond ): 首先释放互斥量,接着阻塞在一定的时间内等待事件发生,然后等待互斥量;

Condition_Signal( Cond ):因为是手动重置事件,当其被调用时,所有正在等待该事件的线程都会变成可调度状态;首先需要了解SetEvent和PulseEvent的区别,因为是手动重置事件,这对于两个函数就有区别了,在自动重置事件类型下事件发生后被等待接收后会自动重置为未触发状态,具体可以查看《Windows核心编程》第9章的内容,里面还介绍了SignalObjectAndWait函数的作用呢。

Condition条件变量定义的宏在使用过程中自己是不太理解的,因为调用的时候容易将等待事件和获取互斥量相互混淆,明明刚释放了互斥量然后永久等待事件发生时,好不容易等到事件发生了又要获取互斥量的所有权,所以写者在每次等待和每次进入以及随后的退出Condition时都加了相应的Debug输出,这样或许能够容易理解点,因为时间的关系,只能将这事放到后面去啃明白,但是在输出的过程中确实能发现其起到的作用,比如报告者在无可奉告的情况下等待输出内容的产生。

 

时间戳:

估计为了与UNIX统一起来,IPerf在Win32上不是直接调用API使用时间,而是自己封装了gettimeofday,先通过GetSystemTimeAsFileTime获取的UTC格式的时间转换成UNIX新纪元下的时间并通过timeval类型进行返回,在该实现函数中使用了几个特殊的数字,这在源代码行上的注释已经说明清楚,这里不再讲述;

TimeStamp这个类中就只有一个类型为timeval的成员变量,成员函数包括获取当前的时间,对时间进行相加减,比较两个时间的先后等,比较容易理解。

时间戳主要用在数据传输过程中给每个发送包赋值,表明这个包发送的时间;还有在-i选项在使用的条件下,计算每次需要打印报告的时间,通过比较将要打印报告的时间和最新发送包的时间戳,决定是否打印这段时间发送的带宽和发送的数据量以及发送的时间段。

 

作为后台服务运行:

仅用于服务端,并且在作为后台服务运行时,-o filename 选项参数才能起到作用,同样也是加入他人实现的文件,稍微看了一下,是通过SCManager的API才创建和执行服务的,这个后面有时间再认真学习,可以考虑自己在后面的某些项目中可以复用。

 

本文暂且就讲到这里,下一篇开始讲解线程和角色,也就是结合着线程讲解客户端、服务端、报告者、监听者的执行过程,暂且仅在TCP模式下,UDP后续再来说明,当然理解了TCP模式下的运行逻辑后,相信UDP模式下也不难理解。

目录
相关文章
|
2月前
|
机器学习/深度学习 PyTorch 算法框架/工具
目标检测实战(一):CIFAR10结合神经网络加载、训练、测试完整步骤
这篇文章介绍了如何使用PyTorch框架,结合CIFAR-10数据集,通过定义神经网络、损失函数和优化器,进行模型的训练和测试。
114 2
目标检测实战(一):CIFAR10结合神经网络加载、训练、测试完整步骤
|
18天前
|
安全 前端开发 测试技术
如何选择合适的自动化安全测试工具
选择合适的自动化安全测试工具需考虑多个因素,包括项目需求、测试目标、系统类型和技术栈,工具的功能特性、市场评价、成本和许可,以及集成性、误报率、社区支持、易用性和安全性。综合评估这些因素,可确保所选工具满足项目需求和团队能力。
|
17天前
|
安全 网络协议 关系型数据库
最好用的17个渗透测试工具
渗透测试是安全人员为防止恶意黑客利用系统漏洞而进行的操作。本文介绍了17款业内常用的渗透测试工具,涵盖网络发现、无线评估、Web应用测试、SQL注入等多个领域,包括Nmap、Aircrack-ng、Burp Suite、OWASP ZAP等,既有免费开源工具,也有付费专业软件,适用于不同需求的安全专家。
36 2
|
16天前
|
监控 网络协议 Java
一些适合性能测试脚本编写和维护的工具
一些适合性能测试脚本编写和维护的工具
|
19天前
|
域名解析 网络协议 测试技术
IP、掩码、网关、DNS1、DNS2到底是什么东西,ping telnet测试
理解IP地址、子网掩码、默认网关和DNS服务器的概念是有效管理和配置网络的基础。通过使用ping和telnet命令,可以测试网络连通性和服务状态,快速诊断和解决网络问题。这些工具和概念是网络管理员和IT专业人员日常工作中不可或缺的部分。希望本文提供的详细解释和示例能够帮助您更好地理解和应用这些网络配置和测试工具。
52 2
|
23天前
|
机器学习/深度学习 自然语言处理 前端开发
前端神经网络入门:Brain.js - 详细介绍和对比不同的实现 - CNN、RNN、DNN、FFNN -无需准备环境打开浏览器即可测试运行-支持WebGPU加速
本文介绍了如何使用 JavaScript 神经网络库 **Brain.js** 实现不同类型的神经网络,包括前馈神经网络(FFNN)、深度神经网络(DNN)和循环神经网络(RNN)。通过简单的示例和代码,帮助前端开发者快速入门并理解神经网络的基本概念。文章还对比了各类神经网络的特点和适用场景,并简要介绍了卷积神经网络(CNN)的替代方案。
|
28天前
|
Web App开发 定位技术 iOS开发
Playwright 是一个强大的工具,用于在各种浏览器上测试应用,并模拟真实设备如手机和平板。通过配置 `playwright.devices`,可以轻松模拟不同设备的用户代理、屏幕尺寸、视口等特性。此外,Playwright 还支持模拟地理位置、区域设置、时区、权限(如通知)和配色方案,使测试更加全面和真实。例如,可以在配置文件中设置全局的区域设置和时区,然后在特定测试中进行覆盖。同时,还可以动态更改地理位置和媒体类型,以适应不同的测试需求。
Playwright 是一个强大的工具,用于在各种浏览器上测试应用,并模拟真实设备如手机和平板。通过配置 `playwright.devices`,可以轻松模拟不同设备的用户代理、屏幕尺寸、视口等特性。此外,Playwright 还支持模拟地理位置、区域设置、时区、权限(如通知)和配色方案,使测试更加全面和真实。例如,可以在配置文件中设置全局的区域设置和时区,然后在特定测试中进行覆盖。同时,还可以动态更改地理位置和媒体类型,以适应不同的测试需求。
33 1
|
1月前
|
编解码 安全 Linux
网络空间安全之一个WH的超前沿全栈技术深入学习之路(10-2):保姆级别教会你如何搭建白帽黑客渗透测试系统环境Kali——Liinux-Debian:就怕你学成黑客啦!)作者——LJS
保姆级别教会你如何搭建白帽黑客渗透测试系统环境Kali以及常见的报错及对应解决方案、常用Kali功能简便化以及详解如何具体实现
|
2月前
|
Java 流计算
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
43 1
Flink-03 Flink Java 3分钟上手 Stream 给 Flink-02 DataStreamSource Socket写一个测试的工具!
|
2月前
|
测试技术 API 开发者
精通.NET单元测试:MSTest、xUnit、NUnit全面解析
【10月更文挑战第15天】本文介绍了.NET生态系统中最流行的三种单元测试框架:MSTest、xUnit和NUnit。通过示例代码展示了每种框架的基本用法和特点,帮助开发者根据项目需求和个人偏好选择合适的测试工具。
40 3

推荐镜像

更多