iperf3 サーバーとクライアントの構成パラメーター交換プロセスのソース コード分析

記事
7、iperf3 ソース コード分析: ステート マシンと状態遷移プロセス —> 順方向 TCP 一方向テスト実行時のサーバー コード
8、iperf3 ソース コード分析: ステート マシンと状態遷移プロセス —> 順方向 TCP 一方向テストの実行クライアントテスト中のコード 9
、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->pointer の下の各パラメーター設定項目に格納してパラメーター交換を完了します。

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 または --sctp テスト -> プロトコル -> ID
未定 -o または –省略 テスト→省略
未定 -A または --affinity テスト -> サーバー アフィニティ)
未定 未定 テスト -> 期間
未定 未定 テスト->設定->バイト
未定 未定 テスト->設定->ブロック
未定 -N、--遅延なし テスト->遅延なし
未定 -M、--set-mss テスト->設定->メッセージ
未定 未定 テスト->ストリーム数
未定 -w、--ウィンドウ テスト->設定->socket_bufsize)
未定 未定 テスト -> 設定 -> ブロックサイズ
未定 未定 テスト -> 設定 -> レート
未定 –fq-rate テスト->設定->fqrate
未定 –ペーシングタイマー テスト->設定->pacing_timer
未定 未定 テスト -> 設定 -> バースト
未定 -S、--彼ら テスト->設定->tos
未定 -L、--フローラベル テスト -> 設定 -> フローラベル
未定 -T、--タイトル テスト→タイトル
未定 –追加データ テスト->追加データ
未定 未定 テスト→輻輳
未定 未定 テスト->輻輳_使用済み
未定 –ドントフラグメント テスト->設定->dont_fragment
未定 -Z、--zerocopy テスト -> ゼロコピー
未定 –繰り返しペイロード テスト -> 繰り返しペイロード
未定 未定 テスト -> 設定 -> レート
未定 -R、--reverse、--bidir テスト→モード
未定 –get-server-output テスト->get_server_output
未定 –udp-counters-64bit テスト->udp_counters_64bit

具体的なソース コードについては、クライアントによって呼び出される send_parameters とサーバーによって呼び出される get_parameters の 2 つの関数を参照してください。

static int
send_parameters(struct iperf_test *test)
{
    
    
    int r = 0;
    cJSON *j;
    PRINTFILEFUNCLINE
    j = 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_SSL
	cJSON_AddStringToObject(j, "client_version", IPERF_VERSION);

	if (test->debug) {
    
    
	    char *str = cJSON_Print(j);
	    printf("send_parameters:\n%s\n", str);
	    cJSON_free(str);
	}
    PRINTFILEFUNCLINE
	if (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;
    PRINTFILEFUNCLINE
    j = 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_SSL
	if (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;
}

おすすめ

転載: blog.csdn.net/meihualing/article/details/129673386