iperf3 服务端和客户端配置参数交换过程源码分析
创始人
2025-05-31 11:15:44

本文目录

  • 1、服务端和客户端配置参数交换过程和状态机变化
  • 2、服务端代码调用过程
  • 3、客户端代码调用过程
  • 4、哪些参数会被客户端同步到服务端

由文章
七,iperf3源代码分析:状态机及状态转换过程—>运行正向TCP单向测试时的服务端代码
八,iperf3源代码分析:状态机及状态转换过程—>运行正向TCP单向测试时的客户端代码
九,iperf3源代码分析:main函数主要流程,正向TCP单向测试时服务端和客户端的交互过程详解
我们知道服务端和客户端配置参数交换过程和状态机变化过程如下(注意:只有iperf3客户端会把配置参数发送给服务端,服务端的参数是不会发送到客户端的):

1、服务端和客户端配置参数交换过程和状态机变化

1)当服务端收到客户端发过来的控制连接建立请求后,就会接收连接请求,并成功的建立连接请求后放在test->ctrl_sck指针里,
2)然后服务端主动进入PARAM_EXCHANGE状态,并给客户端发送PARAM_EXCHANGE指令
3)客户端收到PARAM_EXCHANGE指令后,就开始通过test->ctrl_sck指针指向的控制连接向服务端发送配置参数
4)服务端收到配置参数后,保存并进行配置,进行CREATE_STREAM状态后完成配置参数交换过程

如下图所示左边是客户端,右边是服务端:

在这里插入图片描述

2、服务端代码调用过程

iperf_exchange_parameters—>get_parameters—>JSON_read,
通过test->ctrl_sck 控制连接,将接收到的参数解析后,存入test->指针下的各个参数配置项里,完成参数交换。

debug out: set the state from 15 to 9
debug out: func = iperf_exchange_parameters,line = 2087, file = iperf_api.c
debug out: func = get_parameters           ,line = 2268, file = iperf_api.c
debug out: func = JSON_read                ,line = 2662, file = iperf_api.c
get_parameters:
{"udp":	true,"omit":	0,"time":	0,"num":	8192,"blockcount":	0,"parallel":	1,"len":	1024,"bandwidth":	1048576,"pacing_timer":	1000,"client_version":	"3.13"
}
debug out: func = iperf_exchange_parameters,line = 2104, file = iperf_api.c

3、客户端代码调用过程

iperf_exchange_parameters—>send_parameters—>JSON_write
将客户端的参数以JSON的格式,通过test->ctrl_sck 控制连接,将参数发送到服务端。

debug out: receive and change the state from 0 to 9
debug out: func = iperf_exchange_parameters,line = 2082, file = iperf_api.c
debug out: func = send_parameters          ,line = 2166, file = iperf_api.c
send_parameters:
{"udp":	true,"omit":	0,"time":	0,"num":	8192,"blockcount":	0,"parallel":	1,"len":	1024,"bandwidth":	1048576,"pacing_timer":	1000,"client_version":	"3.13"
}
debug out: func = send_parameters          ,line = 2250, file = iperf_api.c
debug out: func = JSON_write               ,line = 2635, file = iperf_api.c

4、哪些参数会被客户端同步到服务端

通过send_parameters函数,我们可以看到以下参数会被从客户端发送到服务端:

选项名称配置项保存位置
协议类型TCP/UDP/SCTP-u 或者–udp或者–sctptest->protocol->id
TBD-o 或者–omittest->omit
TBD-A或者–affinitytest->server_affinity)
TBDTBDtest->duration
TBDTBDtest->settings->bytes
TBDTBDtest->settings->blocks
TBD-N, --no-delaytest->no_delay
TBD-M, --set-msstest->settings->mss
TBDTBDtest->num_streams
TBD-w, --windowtest->settings->socket_bufsize)
TBDTBDtest->settings->blksize
TBDTBDtest->settings->rate
TBD–fq-ratetest->settings->fqrate
TBD–pacing-timertest->settings->pacing_timer
TBDTBDtest->settings->burst
TBD-S, --tostest->settings->tos
TBD-L, --flowlabeltest->settings->flowlabel
TBD-T, --titletest->title
TBD–extra-datatest->extra_data
TBDTBDtest->congestion
TBDTBDtest->congestion_used
TBD–dont-fragmenttest->settings->dont_fragment
TBD-Z, --zerocopytest->zerocopy
TBD–repeating-payloadtest->repeating_payload
TBDTBDtest->settings->rate
TBD-R, --reverse, --bidirtest->mode
TBD–get-server-outputtest->get_server_output
TBD–udp-counters-64bittest->udp_counters_64bit

具体源代码参见客户端调用的send_parameters和服务端调用的get_parameters二个函数

static int
send_parameters(struct iperf_test *test)
{int r = 0;cJSON *j;PRINTFILEFUNCLINEj = cJSON_CreateObject();if (j == NULL) {i_errno = IESENDPARAMS;r = -1;} else {if (test->protocol->id == Ptcp)cJSON_AddTrueToObject(j, "tcp");else if (test->protocol->id == Pudp)cJSON_AddTrueToObject(j, "udp");else if (test->protocol->id == Psctp)cJSON_AddTrueToObject(j, "sctp");cJSON_AddNumberToObject(j, "omit", test->omit);if (test->server_affinity != -1)cJSON_AddNumberToObject(j, "server_affinity", test->server_affinity);cJSON_AddNumberToObject(j, "time", test->duration);cJSON_AddNumberToObject(j, "num", test->settings->bytes);cJSON_AddNumberToObject(j, "blockcount", test->settings->blocks);if (test->settings->mss)cJSON_AddNumberToObject(j, "MSS", test->settings->mss);if (test->no_delay)cJSON_AddTrueToObject(j, "nodelay");cJSON_AddNumberToObject(j, "parallel", test->num_streams);if (test->reverse)cJSON_AddTrueToObject(j, "reverse");if (test->bidirectional)cJSON_AddTrueToObject(j, "bidirectional");if (test->settings->socket_bufsize)cJSON_AddNumberToObject(j, "window", test->settings->socket_bufsize);if (test->settings->blksize)cJSON_AddNumberToObject(j, "len", test->settings->blksize);if (test->settings->rate)cJSON_AddNumberToObject(j, "bandwidth", test->settings->rate);if (test->settings->fqrate)cJSON_AddNumberToObject(j, "fqrate", test->settings->fqrate);if (test->settings->pacing_timer)cJSON_AddNumberToObject(j, "pacing_timer", test->settings->pacing_timer);if (test->settings->burst)cJSON_AddNumberToObject(j, "burst", test->settings->burst);if (test->settings->tos)cJSON_AddNumberToObject(j, "TOS", test->settings->tos);if (test->settings->flowlabel)cJSON_AddNumberToObject(j, "flowlabel", test->settings->flowlabel);if (test->title)cJSON_AddStringToObject(j, "title", test->title);if (test->extra_data)cJSON_AddStringToObject(j, "extra_data", test->extra_data);if (test->congestion)cJSON_AddStringToObject(j, "congestion", test->congestion);if (test->congestion_used)cJSON_AddStringToObject(j, "congestion_used", test->congestion_used);if (test->get_server_output)cJSON_AddNumberToObject(j, "get_server_output", iperf_get_test_get_server_output(test));if (test->udp_counters_64bit)cJSON_AddNumberToObject(j, "udp_counters_64bit", iperf_get_test_udp_counters_64bit(test));if (test->repeating_payload)cJSON_AddNumberToObject(j, "repeating_payload", test->repeating_payload);if (test->zerocopy)cJSON_AddNumberToObject(j, "zerocopy", test->zerocopy);
#if defined(HAVE_DONT_FRAGMENT)if (test->settings->dont_fragment)cJSON_AddNumberToObject(j, "dont_fragment", test->settings->dont_fragment);
#endif /* HAVE_DONT_FRAGMENT */
#if defined(HAVE_SSL)/* Send authentication parameters */if (test->settings->client_username && test->settings->client_password && test->settings->client_rsa_pubkey){int rc = encode_auth_setting(test->settings->client_username, test->settings->client_password, test->settings->client_rsa_pubkey, &test->settings->authtoken);if (rc) {cJSON_Delete(j);i_errno = IESENDPARAMS;return -1;}cJSON_AddStringToObject(j, "authtoken", test->settings->authtoken);}
#endif // HAVE_SSLcJSON_AddStringToObject(j, "client_version", IPERF_VERSION);if (test->debug) {char *str = cJSON_Print(j);printf("send_parameters:\n%s\n", str);cJSON_free(str);}PRINTFILEFUNCLINEif (JSON_write(test->ctrl_sck, j) < 0) {i_errno = IESENDPARAMS;r = -1;}cJSON_Delete(j);}return r;
}#----------------------------------------------------------------------------
static int
get_parameters(struct iperf_test *test)
{int r = 0;cJSON *j;cJSON *j_p;PRINTFILEFUNCLINEj = JSON_read(test->ctrl_sck);if (j == NULL) {i_errno = IERECVPARAMS;r = -1;} else {if (test->debug) {char *str;str = cJSON_Print(j);printf("get_parameters:\n%s\n", str );cJSON_free(str);}if ((j_p = cJSON_GetObjectItem(j, "tcp")) != NULL)set_protocol(test, Ptcp);if ((j_p = cJSON_GetObjectItem(j, "udp")) != NULL)set_protocol(test, Pudp);if ((j_p = cJSON_GetObjectItem(j, "sctp")) != NULL)set_protocol(test, Psctp);if ((j_p = cJSON_GetObjectItem(j, "omit")) != NULL)test->omit = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "server_affinity")) != NULL)test->server_affinity = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "time")) != NULL)test->duration = j_p->valueint;test->settings->bytes = 0;if ((j_p = cJSON_GetObjectItem(j, "num")) != NULL)test->settings->bytes = j_p->valueint;test->settings->blocks = 0;if ((j_p = cJSON_GetObjectItem(j, "blockcount")) != NULL)test->settings->blocks = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "MSS")) != NULL)test->settings->mss = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "nodelay")) != NULL)test->no_delay = 1;if ((j_p = cJSON_GetObjectItem(j, "parallel")) != NULL)test->num_streams = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "reverse")) != NULL)iperf_set_test_reverse(test, 1);if ((j_p = cJSON_GetObjectItem(j, "bidirectional")) != NULL)iperf_set_test_bidirectional(test, 1);if ((j_p = cJSON_GetObjectItem(j, "window")) != NULL)test->settings->socket_bufsize = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "len")) != NULL)test->settings->blksize = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "bandwidth")) != NULL)test->settings->rate = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "fqrate")) != NULL)test->settings->fqrate = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "pacing_timer")) != NULL)test->settings->pacing_timer = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "burst")) != NULL)test->settings->burst = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "TOS")) != NULL)test->settings->tos = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "flowlabel")) != NULL)test->settings->flowlabel = j_p->valueint;if ((j_p = cJSON_GetObjectItem(j, "title")) != NULL)test->title = strdup(j_p->valuestring);if ((j_p = cJSON_GetObjectItem(j, "extra_data")) != NULL)test->extra_data = strdup(j_p->valuestring);if ((j_p = cJSON_GetObjectItem(j, "congestion")) != NULL)test->congestion = strdup(j_p->valuestring);if ((j_p = cJSON_GetObjectItem(j, "congestion_used")) != NULL)test->congestion_used = strdup(j_p->valuestring);if ((j_p = cJSON_GetObjectItem(j, "get_server_output")) != NULL)iperf_set_test_get_server_output(test, 1);if ((j_p = cJSON_GetObjectItem(j, "udp_counters_64bit")) != NULL)iperf_set_test_udp_counters_64bit(test, 1);if ((j_p = cJSON_GetObjectItem(j, "repeating_payload")) != NULL)test->repeating_payload = 1;if ((j_p = cJSON_GetObjectItem(j, "zerocopy")) != NULL)test->zerocopy = j_p->valueint;
#if defined(HAVE_DONT_FRAGMENT)if ((j_p = cJSON_GetObjectItem(j, "dont_fragment")) != NULL)test->settings->dont_fragment = j_p->valueint;
#endif /* HAVE_DONT_FRAGMENT */
#if defined(HAVE_SSL)if ((j_p = cJSON_GetObjectItem(j, "authtoken")) != NULL)test->settings->authtoken = strdup(j_p->valuestring);
#endif //HAVE_SSLif (test->mode && test->protocol->id == Ptcp && has_tcpinfo_retransmits())test->sender_has_retransmits = 1;if (test->settings->rate)cJSON_AddNumberToObject(test->json_start, "target_bitrate", test->settings->rate);cJSON_Delete(j);}return r;
}

相关内容

热门资讯

【开源协议】关于6种开源协议的... 关于开源协议的说明前言开源协议分为 宽松型 和 著作权型。如何选择?开源协议(GPL,...
easymock不能用了?fa... 什么是fast mock 前端常常要等待后面接口写好后,才能集成测试,免...
GIS的一些简单算法(自己作记... 一、线的矢量算法 1、简单的线相交算法 算法1:快速排斥与矢量跨立         快...
催债令来了!国家急了,严禁机关... 作者 | 剑书发现没有,当前国家摆在最高优先级的一件大事,竟然是给中小企业还清欠款。就在6月1日,国...
数据分析思维|思考问题的25个... 逻辑思维:能够理性分析问题,梳理出问题的本质和关键点,建立...
三、Docker:Compos...   Docker-compose 是用于定义和运行多容器 Docker 应用程序的编排工具。使用 d...
理想汽车5月交付40856辆,... 新京报贝壳财经讯 6月1日,理想汽车公布2025年5月交付数据。5月份,理想汽车交付新车40856辆...
新宙邦:公司对高性能电子材料均... 证券日报网讯 新宙邦5月30日在互动平台回答投资者提问时表示,公司对高性能电子材料均做了一些布局。其...
电商酒水类产品打假有哪些操作(... 线上酒水类产品蓬勃发展,但产品假货问题也随之而来,不仅损害了品牌商家的合法权益,还对消费者的健康和安...
今年很火的AI绘画怎么玩 1.前言 2022年绝对可以说是AIGC元年,从google搜索的趋势来看࿰...
canvas 教程 指南 万字... 前端妹子问我为什么官网上面只有一个canvas标签,里面什么都没有… 我脸色一变”完了...
开发一个app需要多少钱 APP应用开发主要分为原生APP和HTML5APP开发,使用HTML5开发的app价格...
vue项目的创建 npm install postcss postcss-pxtorem --save-dev 什么是...
二十六、对象的实例化内存布局与... 一、对象的实例化 1.判断对象对用的类是否加载、链接、初始化。 2.为对象分配内存。 3.处理并发...
助力私募行业高质量发展,华西证...   践行传播行业文化,进一步促进私募行业高质量发展,资本市场这场现象级行...
创建索引,解决mysql数据查... 实战场景 :两个表 T_PLATFORM A left join T_OPER_REC...
5. Python中的异常处理... 1. 说明: 自己写的代码保证万无一失有点难度,代码报出异常后ÿ...
图神经网络(GCN) 一、GCN的起源 曾经深度学习一直都是被几大经典模型给统治着,如CNN、RNN等等&#...
5月汽车销量出炉:理想力压小鹏... 【市场】6月第一天,多家汽车企业公布了5月的销量数据,和去年相比实现了两位数增长,但排名发生了变化。...
Python数据结构与算法(p... 主要内容:什么是列表查找顺序查找二分查找一、什么是查找?(...
状态机DP 状态机DP算法特征子数组类DP问题的定义:以最后一个元素结尾的最大xxx特征1...
mendeley管理文献样式 编辑GB/T 7714—2005参考文件样式,解决:显示大小写ÿ...
多次谋求A股上市!锂电巨头业绩... 知名锂电池生产企业天津力神电池股份有限公司(下称“天津力神”)的经营情况曝光。证券时报·e公司记者在...
前沿技术揭秘:云原生-展望容器... 2023年最火热的就是ChatGPT,当然还有5G技术、AI、机器学习、区块链等技术。另外还有一个现...
WalletConnect的下... 加密行业中每一个项目都有它自己的作用,很多我们意想不到或者认为的事情往往最后都会出现转...
独家 | 大润发佘咸平任永辉C... 交流永辉,实名添加微信lihua759321进群多位市场人士向《商业观察家》确认,大润发M会员店商品...
拼多多管理层多次强调利润不可持... 近日,拼多多一季度财报引起市场热议。财报显示,拼多多一季度营收957亿元,同比增长10%,归母净利润...
实战项目:保险行业用户分类 这里写目录标题1、项目介绍1.1 行业背景1.2 数据介绍2、代码实现导入数据探索数据处理列标签名异...
矿泉水瓶装大米,便利店能增收3... 矿泉水瓶装大米,便利店能增收300万 把大米装进矿泉水瓶,一瓶卖到60块...
港股迎来打新热!“散户失权”引... 港股行情提振,新股表现亮眼,打新又热了。Wind显示,2025年港股已迎来27只新股,其中仅7只上市...