Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2392,6 +2392,10 @@ iperf_exchange_results(struct iperf_test *test)
/* Get client results. */
if (get_results(test) < 0)
return -1;

/* Report results once client's results are received */
test->reporter_callback(test);

/* Send results to client. */
if (send_results(test) < 0)
return -1;
Expand Down Expand Up @@ -4553,6 +4557,7 @@ iperf_reporter_callback(struct iperf_test *test)
iperf_print_intermediate(test);
break;
case TEST_END:
case EXCHANGE_RESULTS:
case DISPLAY_RESULTS:
iperf_print_intermediate(test);
iperf_print_results(test);
Expand Down
1 change: 0 additions & 1 deletion src/iperf_server_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ iperf_handle_message_server(struct iperf_test *test)
FD_CLR(sp->socket, &test->write_set);
close(sp->socket);
}
test->reporter_callback(test);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that the right change is to move this call to reporter_callback after setting the state to DISPLAY_RESULTS, i.e. move this line after original line 284 below. With this change, all other changes in this PR should probably be undone.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was the change I made in my first attempt, but then I saw that it broke the --get-server-output flag on the client side. My understanding is that at the test's end, the call to reporter_callback populates the (potentially) last interval in the JSON and then populates the end field, so moving the call to after setting the state to DISPLAY_RESULTS would give the client a JSON result with a (potentially) missing interval and missing end. In this snippet, the last interval on the server side was discarded instead of added to the JSON so both the client and server have 4 intervals, but I have seen cases where the server has one more wualified interval that this change never appends. The end is always missing:

Client JSON w/Server Json (First Attempt)
{
	"start":	{
		"connected":	[{
				"socket":	5,
				"local_host":	"127.0.0.1",
				"local_port":	64953,
				"remote_host":	"127.0.0.1",
				"remote_port":	5201
			}],
		"version":	"iperf 3.19.1+",
		"system_info":	"Darwin CASML-K204175 24.6.0 Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:31 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6030 arm64",
		"timestamp":	{
			"time":	"Wed, 22 Oct 2025 01:05:27 UTC",
			"timesecs":	1761095127,
			"timemillisecs":	1761095127061
		},
		"connecting_to":	{
			"host":	"127.0.0.1",
			"port":	5201
		},
		"cookie":	"44tsufxw2whdis7ollqo5w62gm5hyjtpagwq",
		"tcp_mss_default":	16332,
		"target_bitrate":	170000000,
		"fq_rate":	0,
		"sock_bufsize":	0,
		"sndbuf_actual":	131072,
		"rcvbuf_actual":	131072,
		"test_start":	{
			"protocol":	"TCP",
			"num_streams":	1,
			"blksize":	131072,
			"omit":	0,
			"duration":	4,
			"bytes":	0,
			"blocks":	0,
			"reverse":	1,
			"tos":	0,
			"target_bitrate":	170000000,
			"bidir":	0,
			"fqrate":	0,
			"interval":	1
		}
	},
	"intervals":	[{
			"streams":	[{
					"socket":	5,
					"start":	0,
					"end":	1.005023,
					"seconds":	1.0050230026245117,
					"bytes":	21364736,
					"bits_per_second":	170063657.80053386,
					"omitted":	false,
					"sender":	false
				}],
			"sum":	{
				"start":	0,
				"end":	1.005023,
				"seconds":	1.0050230026245117,
				"bytes":	21364736,
				"bits_per_second":	170063657.80053386,
				"omitted":	false,
				"sender":	false
			}
		}, {
			"streams":	[{
					"socket":	5,
					"start":	1.005023,
					"end":	2.005025,
					"seconds":	1.0000020265579224,
					"bytes":	21233664,
					"bits_per_second":	169868967.75069764,
					"omitted":	false,
					"sender":	false
				}],
			"sum":	{
				"start":	1.005023,
				"end":	2.005025,
				"seconds":	1.0000020265579224,
				"bytes":	21233664,
				"bits_per_second":	169868967.75069764,
				"omitted":	false,
				"sender":	false
			}
		}, {
			"streams":	[{
					"socket":	5,
					"start":	2.005025,
					"end":	3.001299,
					"seconds":	0.99627399444580078,
					"bytes":	21233664,
					"bits_per_second":	170504613.13555968,
					"omitted":	false,
					"sender":	false
				}],
			"sum":	{
				"start":	2.005025,
				"end":	3.001299,
				"seconds":	0.99627399444580078,
				"bytes":	21233664,
				"bits_per_second":	170504613.13555968,
				"omitted":	false,
				"sender":	false
			}
		}, {
			"streams":	[{
					"socket":	5,
					"start":	3.001299,
					"end":	4.004282,
					"seconds":	1.0029829740524292,
					"bytes":	21233664,
					"bits_per_second":	169364103.27451918,
					"omitted":	false,
					"sender":	false
				}],
			"sum":	{
				"start":	3.001299,
				"end":	4.004282,
				"seconds":	1.0029829740524292,
				"bytes":	21233664,
				"bits_per_second":	169364103.27451918,
				"omitted":	false,
				"sender":	false
			}
		}],
	"end":	{
		"streams":	[{
				"sender":	{
					"socket":	5,
					"start":	0,
					"end":	4.0049,
					"seconds":	4.0049,
					"bytes":	85196800,
					"bits_per_second":	170185123.22405052,
					"sender":	false
				},
				"receiver":	{
					"socket":	5,
					"start":	0,
					"end":	4.004282,
					"seconds":	4.004282,
					"bytes":	85065728,
					"bits_per_second":	169949525.03345171,
					"sender":	false
				}
			}],
		"sum_sent":	{
			"start":	0,
			"end":	4.0049,
			"seconds":	4.0049,
			"bytes":	85196800,
			"bits_per_second":	170185123.22405052,
			"sender":	false
		},
		"sum_received":	{
			"start":	0,
			"end":	4.004282,
			"seconds":	4.004282,
			"bytes":	85065728,
			"bits_per_second":	169949525.03345171,
			"sender":	false
		},
		"cpu_utilization_percent":	{
			"host_total":	5.1971978267434347,
			"host_user":	0.068432125663544535,
			"host_system":	5.1289154431491752,
			"remote_total":	9.33060535336937,
			"remote_user":	0.11053911978700184,
			"remote_system":	9.22014114150181
		}
	},
	"server_output_json":	{
		"start":	{
			"connected":	[{
					"socket":	5,
					"local_host":	"127.0.0.1",
					"local_port":	5201,
					"remote_host":	"127.0.0.1",
					"remote_port":	64953
				}],
			"version":	"iperf 3.19.1+",
			"system_info":	"Darwin CASML-K204175 24.6.0 Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:31 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6030 arm64",
			"target_bitrate":	170000000,
			"sock_bufsize":	0,
			"sndbuf_actual":	131072,
			"rcvbuf_actual":	131072,
			"timestamp":	{
				"time":	"Wed, 22 Oct 2025 01:05:27 UTC",
				"timesecs":	1761095127,
				"timemillisecs":	1761095127061
			},
			"accepted_connection":	{
				"host":	"127.0.0.1",
				"port":	64952
			},
			"cookie":	"44tsufxw2whdis7ollqo5w62gm5hyjtpagwq",
			"tcp_mss_default":	0,
			"target_bitrate":	170000000,
			"fq_rate":	0,
			"test_start":	{
				"protocol":	"TCP",
				"num_streams":	1,
				"blksize":	131072,
				"omit":	0,
				"duration":	4,
				"bytes":	0,
				"blocks":	0,
				"reverse":	1,
				"tos":	0,
				"target_bitrate":	170000000,
				"bidir":	0,
				"fqrate":	0,
				"interval":	1
			}
		},
		"intervals":	[{
				"streams":	[{
						"socket":	5,
						"start":	0,
						"end":	1.005005,
						"seconds":	1.0050050020217896,
						"bytes":	21364736,
						"bits_per_second":	170066703.80362377,
						"omitted":	false,
						"sender":	true
					}],
				"sum":	{
					"start":	0,
					"end":	1.005005,
					"seconds":	1.0050050020217896,
					"bytes":	21364736,
					"bits_per_second":	170066703.80362377,
					"omitted":	false,
					"sender":	true
				}
			}, {
				"streams":	[{
						"socket":	5,
						"start":	1.005005,
						"end":	2.002644,
						"seconds":	0.997639000415802,
						"bytes":	21233664,
						"bits_per_second":	170271322.52167451,
						"omitted":	false,
						"sender":	true
					}],
				"sum":	{
					"start":	1.005005,
					"end":	2.002644,
					"seconds":	0.997639000415802,
					"bytes":	21233664,
					"bits_per_second":	170271322.52167451,
					"omitted":	false,
					"sender":	true
				}
			}, {
				"streams":	[{
						"socket":	5,
						"start":	2.002644,
						"end":	3.005021,
						"seconds":	1.0023770332336426,
						"bytes":	21233664,
						"bits_per_second":	169466484.53427345,
						"omitted":	false,
						"sender":	true
					}],
				"sum":	{
					"start":	2.002644,
					"end":	3.005021,
					"seconds":	1.0023770332336426,
					"bytes":	21233664,
					"bits_per_second":	169466484.53427345,
					"omitted":	false,
					"sender":	true
				}
			}, {
				"streams":	[{
						"socket":	5,
						"start":	3.005021,
						"end":	4.00263,
						"seconds":	0.99760901927948,
						"bytes":	21233664,
						"bits_per_second":	170276439.68444431,
						"omitted":	false,
						"sender":	true
					}],
				"sum":	{
					"start":	3.005021,
					"end":	4.00263,
					"seconds":	0.99760901927948,
					"bytes":	21233664,
					"bits_per_second":	170276439.68444431,
					"omitted":	false,
					"sender":	true
				}
			}],
		"end":	{
		}
	}
}

My most recent change adjusts the order of operations, where the server first acquires the Client's results, takes what it needs from those results and inserts them into its results, and then sends its results back to the Client.

Client JSON w/Server Json (Final)
{
	"start":	{
		"connected":	[{
				"socket":	5,
				"local_host":	"127.0.0.1",
				"local_port":	60354,
				"remote_host":	"127.0.0.1",
				"remote_port":	5201
			}],
		"version":	"iperf 3.19.1+",
		"system_info":	"Darwin CASML-K204175 24.6.0 Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:31 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6030 arm64",
		"timestamp":	{
			"time":	"Wed, 22 Oct 2025 15:43:56 UTC",
			"timesecs":	1761147836,
			"timemillisecs":	1761147836394
		},
		"connecting_to":	{
			"host":	"127.0.0.1",
			"port":	5201
		},
		"cookie":	"oavle55tz4jfn4u4i4gqvcmect33esyt72jx",
		"tcp_mss_default":	16332,
		"target_bitrate":	170000000,
		"fq_rate":	0,
		"sock_bufsize":	0,
		"sndbuf_actual":	131072,
		"rcvbuf_actual":	131072,
		"test_start":	{
			"protocol":	"TCP",
			"num_streams":	1,
			"blksize":	131072,
			"omit":	0,
			"duration":	4,
			"bytes":	0,
			"blocks":	0,
			"reverse":	1,
			"tos":	0,
			"target_bitrate":	170000000,
			"bidir":	0,
			"fqrate":	0,
			"interval":	1
		}
	},
	"intervals":	[{
			"streams":	[{
					"socket":	5,
					"start":	0,
					"end":	1.000461,
					"seconds":	1.0004609823226929,
					"bytes":	21233664,
					"bits_per_second":	169791041.33139461,
					"omitted":	false,
					"sender":	false
				}],
			"sum":	{
				"start":	0,
				"end":	1.000461,
				"seconds":	1.0004609823226929,
				"bytes":	21233664,
				"bits_per_second":	169791041.33139461,
				"omitted":	false,
				"sender":	false
			}
		}, {
			"streams":	[{
					"socket":	5,
					"start":	1.000461,
					"end":	2.005027,
					"seconds":	1.004565954208374,
					"bytes":	21364736,
					"bits_per_second":	170141031.83965462,
					"omitted":	false,
					"sender":	false
				}],
			"sum":	{
				"start":	1.000461,
				"end":	2.005027,
				"seconds":	1.004565954208374,
				"bytes":	21364736,
				"bits_per_second":	170141031.83965462,
				"omitted":	false,
				"sender":	false
			}
		}, {
			"streams":	[{
					"socket":	5,
					"start":	2.005027,
					"end":	3.004404,
					"seconds":	0.99937701225280762,
					"bytes":	21233664,
					"bits_per_second":	169975204.46971115,
					"omitted":	false,
					"sender":	false
				}],
			"sum":	{
				"start":	2.005027,
				"end":	3.004404,
				"seconds":	0.99937701225280762,
				"bytes":	21233664,
				"bits_per_second":	169975204.46971115,
				"omitted":	false,
				"sender":	false
			}
		}, {
			"streams":	[{
					"socket":	5,
					"start":	3.004404,
					"end":	4.003841,
					"seconds":	0.99943697452545166,
					"bytes":	21233664,
					"bits_per_second":	169965006.62851363,
					"omitted":	false,
					"sender":	false
				}],
			"sum":	{
				"start":	3.004404,
				"end":	4.003841,
				"seconds":	0.99943697452545166,
				"bytes":	21233664,
				"bits_per_second":	169965006.62851363,
				"omitted":	false,
				"sender":	false
			}
		}],
	"end":	{
		"streams":	[{
				"sender":	{
					"socket":	5,
					"start":	0,
					"end":	4.004357,
					"seconds":	4.004357,
					"bytes":	85065728,
					"bits_per_second":	169946341.94703421,
					"sender":	false
				},
				"receiver":	{
					"socket":	5,
					"start":	0,
					"end":	4.003841,
					"seconds":	4.003841,
					"bytes":	85065728,
					"bits_per_second":	169968243.993705,
					"sender":	false
				}
			}],
		"sum_sent":	{
			"start":	0,
			"end":	4.004357,
			"seconds":	4.004357,
			"bytes":	85065728,
			"bits_per_second":	169946341.94703421,
			"sender":	false
		},
		"sum_received":	{
			"start":	0,
			"end":	4.003841,
			"seconds":	4.003841,
			"bytes":	85065728,
			"bits_per_second":	169968243.993705,
			"sender":	false
		},
		"cpu_utilization_percent":	{
			"host_total":	5.85302413254988,
			"host_user":	0.071980644596251531,
			"host_system":	5.78116789280084,
			"remote_total":	11.173274335841226,
			"remote_user":	0.096386986258611779,
			"remote_system":	11.076762495973473
		}
	},
	"server_output_json":	{
		"start":	{
			"connected":	[{
					"socket":	5,
					"local_host":	"127.0.0.1",
					"local_port":	5201,
					"remote_host":	"127.0.0.1",
					"remote_port":	60354
				}],
			"version":	"iperf 3.19.1+",
			"system_info":	"Darwin CASML-K204175 24.6.0 Darwin Kernel Version 24.6.0: Mon Aug 11 21:16:31 PDT 2025; root:xnu-11417.140.69.701.11~1/RELEASE_ARM64_T6030 arm64",
			"target_bitrate":	170000000,
			"sock_bufsize":	0,
			"sndbuf_actual":	131072,
			"rcvbuf_actual":	131072,
			"timestamp":	{
				"time":	"Wed, 22 Oct 2025 15:43:56 UTC",
				"timesecs":	1761147836,
				"timemillisecs":	1761147836394
			},
			"accepted_connection":	{
				"host":	"127.0.0.1",
				"port":	60353
			},
			"cookie":	"oavle55tz4jfn4u4i4gqvcmect33esyt72jx",
			"tcp_mss_default":	0,
			"target_bitrate":	170000000,
			"fq_rate":	0,
			"test_start":	{
				"protocol":	"TCP",
				"num_streams":	1,
				"blksize":	131072,
				"omit":	0,
				"duration":	4,
				"bytes":	0,
				"blocks":	0,
				"reverse":	1,
				"tos":	0,
				"target_bitrate":	170000000,
				"bidir":	0,
				"fqrate":	0,
				"interval":	1
			}
		},
		"intervals":	[{
				"streams":	[{
						"socket":	5,
						"start":	0,
						"end":	1.002389,
						"seconds":	1.0023889541625977,
						"bytes":	21364736,
						"bits_per_second":	170510546.12107724,
						"omitted":	false,
						"sender":	true
					}],
				"sum":	{
					"start":	0,
					"end":	1.002389,
					"seconds":	1.0023889541625977,
					"bytes":	21364736,
					"bits_per_second":	170510546.12107724,
					"omitted":	false,
					"sender":	true
				}
			}, {
				"streams":	[{
						"socket":	5,
						"start":	1.002389,
						"end":	2.000762,
						"seconds":	0.998372972011566,
						"bytes":	21233664,
						"bits_per_second":	170146144.53928953,
						"omitted":	false,
						"sender":	true
					}],
				"sum":	{
					"start":	1.002389,
					"end":	2.000762,
					"seconds":	0.998372972011566,
					"bytes":	21233664,
					"bits_per_second":	170146144.53928953,
					"omitted":	false,
					"sender":	true
				}
			}, {
				"streams":	[{
						"socket":	5,
						"start":	2.000762,
						"end":	3.004524,
						"seconds":	1.0037620067596436,
						"bytes":	21233664,
						"bits_per_second":	169232657.59816328,
						"omitted":	false,
						"sender":	true
					}],
				"sum":	{
					"start":	2.000762,
					"end":	3.004524,
					"seconds":	1.0037620067596436,
					"bytes":	21233664,
					"bits_per_second":	169232657.59816328,
					"omitted":	false,
					"sender":	true
				}
			}, {
				"streams":	[{
						"socket":	5,
						"start":	3.004524,
						"end":	4.004357,
						"seconds":	0.99983298778533936,
						"bytes":	21233664,
						"bits_per_second":	169897686.98896974,
						"omitted":	false,
						"sender":	true
					}],
				"sum":	{
					"start":	3.004524,
					"end":	4.004357,
					"seconds":	0.99983298778533936,
					"bytes":	21233664,
					"bits_per_second":	169897686.98896974,
					"omitted":	false,
					"sender":	true
				}
			}],
		"end":	{
			"streams":	[{
					"sender":	{
						"socket":	5,
						"start":	0,
						"end":	4.004357,
						"seconds":	4.004357,
						"bytes":	85065728,
						"bits_per_second":	169946341.94703421,
						"sender":	true
					},
					"receiver":	{
						"socket":	5,
						"start":	0,
						"end":	4.003841,
						"seconds":	4.004357,
						"bytes":	85065728,
						"bits_per_second":	169968243.993705,
						"sender":	true
					}
				}],
			"sum_sent":	{
				"start":	0,
				"end":	4.004357,
				"seconds":	4.004357,
				"bytes":	85065728,
				"bits_per_second":	169946341.94703421,
				"sender":	true
			},
			"sum_received":	{
				"start":	0,
				"end":	4.003841,
				"seconds":	4.003841,
				"bytes":	85065728,
				"bits_per_second":	169968243.993705,
				"sender":	true
			},
			"cpu_utilization_percent":	{
				"host_total":	11.173274335841226,
				"host_user":	0.096386986258611779,
				"host_system":	11.076762495973473,
				"remote_total":	5.85302413254988,
				"remote_user":	0.071980644596251531,
				"remote_system":	5.78116789280084
			}
		}
	}
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Thanks for the explanation.

if (iperf_set_send_state(test, EXCHANGE_RESULTS) != 0)
return -1;
if (iperf_exchange_results(test) < 0)
Expand Down