1
1
Этот коммит содержится в:
Jef Poskanzer 2013-12-19 10:31:22 -08:00
родитель c2cb7b7520
Коммит f11d3fa332
8 изменённых файлов: 72 добавлений и 31 удалений

Просмотреть файл

@ -80,6 +80,7 @@ struct iperf_settings
int tos; /* type of service bit */ int tos; /* type of service bit */
int flowlabel; /* IPv6 flow label */ int flowlabel; /* IPv6 flow label */
iperf_size_t bytes; /* number of bytes to send */ iperf_size_t bytes; /* number of bytes to send */
int blocks; /* number of blocks (packets) to send */
char unit_format; /* -f */ char unit_format; /* -f */
}; };
@ -201,6 +202,7 @@ struct iperf_test
int num_streams; /* total streams in the test (-P) */ int num_streams; /* total streams in the test (-P) */
iperf_size_t bytes_sent; iperf_size_t bytes_sent;
int blocks_sent;
char cookie[COOKIE_SIZE]; char cookie[COOKIE_SIZE];
// struct iperf_stream *streams; /* pointer to list of struct stream */ // struct iperf_stream *streams; /* pointer to list of struct stream */
SLIST_HEAD(slisthead, iperf_stream) streams; SLIST_HEAD(slisthead, iperf_stream) streams;

Просмотреть файл

@ -84,6 +84,9 @@ time in seconds to transmit for (default 10 secs)
.BR -n ", " --bytes " \fIn\fR[KM]" .BR -n ", " --bytes " \fIn\fR[KM]"
number of bytes to transmit (instead of -t) number of bytes to transmit (instead of -t)
.TP .TP
.BR -k ", " --blockcount " \fIn\fR[KM]"
number of blocks (packets) to transmit (instead of -t or -n)
.TP
.BR -l ", " --length " \fIn\fR[KM]" .BR -l ", " --length " \fIn\fR[KM]"
length of buffer to read or write (default 128 KB for TCP, 8KB for UDP) length of buffer to read or write (default 128 KB for TCP, 8KB for UDP)
.TP .TP

Просмотреть файл

@ -388,14 +388,13 @@ void
iperf_on_test_start(struct iperf_test *test) iperf_on_test_start(struct iperf_test *test)
{ {
if (test->json_output) { if (test->json_output) {
if (test->settings->bytes) cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s num_streams: %d blksize: %d omit: %d duration: %d bytes: %d blocks: %d", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->duration, (int64_t) test->settings->bytes, (int64_t) test->settings->blocks));
cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s num_streams: %d blksize: %d omit: %d bytes: %d", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->settings->bytes));
else
cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s num_streams: %d blksize: %d omit: %d duration: %d", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->duration));
} else { } else {
if (test->verbose) { if (test->verbose) {
if (test->settings->bytes) if (test->settings->bytes)
iprintf(test, test_start_bytes, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->bytes); iprintf(test, test_start_bytes, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->bytes);
else if (test->settings->blocks)
iprintf(test, test_start_blocks, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->blocks);
else else
iprintf(test, test_start_time, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->duration); iprintf(test, test_start_time, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->duration);
} }
@ -515,6 +514,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"bandwidth", required_argument, NULL, 'b'}, {"bandwidth", required_argument, NULL, 'b'},
{"time", required_argument, NULL, 't'}, {"time", required_argument, NULL, 't'},
{"bytes", required_argument, NULL, 'n'}, {"bytes", required_argument, NULL, 'n'},
{"blockcount", required_argument, NULL, 'k'},
{"length", required_argument, NULL, 'l'}, {"length", required_argument, NULL, 'l'},
{"parallel", required_argument, NULL, 'P'}, {"parallel", required_argument, NULL, 'P'},
{"reverse", no_argument, NULL, 'R'}, {"reverse", no_argument, NULL, 'R'},
@ -539,13 +539,13 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
}; };
int flag; int flag;
int blksize; int blksize;
int server_flag, client_flag, rate_flag; int server_flag, client_flag, rate_flag, duration_flag;
char* comma; char* comma;
char* slash; char* slash;
blksize = 0; blksize = 0;
server_flag = client_flag = rate_flag = 0; server_flag = client_flag = rate_flag = duration_flag = 0;
while ((flag = getopt_long(argc, argv, "p:f:i:DVJvsc:ub:t:n:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:h", longopts, NULL)) != -1) { while ((flag = getopt_long(argc, argv, "p:f:i:DVJvsc:ub:t:n:k:l:P:Rw:B:M:N46S:L:ZO:F:A:T:C:h", longopts, NULL)) != -1) {
switch (flag) { switch (flag) {
case 'p': case 'p':
test->server_port = atoi(optarg); test->server_port = atoi(optarg);
@ -617,12 +617,17 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
i_errno = IEDURATION; i_errno = IEDURATION;
return -1; return -1;
} }
duration_flag = 1;
client_flag = 1; client_flag = 1;
break; break;
case 'n': case 'n':
test->settings->bytes = unit_atoi(optarg); test->settings->bytes = unit_atoi(optarg);
client_flag = 1; client_flag = 1;
break; break;
case 'k':
test->settings->blocks = unit_atoi(optarg);
client_flag = 1;
break;
case 'l': case 'l':
blksize = unit_atoi(optarg); blksize = unit_atoi(optarg);
client_flag = 1; client_flag = 1;
@ -767,6 +772,21 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
if (!rate_flag) if (!rate_flag)
test->settings->rate = test->protocol->id == Pudp ? UDP_RATE : 0; test->settings->rate = test->protocol->id == Pudp ? UDP_RATE : 0;
if ((test->settings->bytes != 0 || test->settings->blocks != 0) && ! duration_flag)
test->duration = 0;
/* Disallow specifying multiple test end conditions. The code actually
** works just fine without this prohibition. As soon as any one of the
** three possible end conditions is met, the test ends. So this check
** could be removed if desired.
*/
if ((duration_flag && test->settings->bytes != 0) ||
(duration_flag && test->settings->blocks != 0) ||
(test->settings->bytes != 0 && test->settings->blocks != 0)) {
i_errno = IEENDCONDITIONS;
return -1;
}
/* For subsequent calls to getopt */ /* For subsequent calls to getopt */
#ifdef __APPLE__ #ifdef __APPLE__
optreset = 1; optreset = 1;
@ -839,10 +859,13 @@ iperf_send(struct iperf_test *test, fd_set *write_setP)
return r; return r;
} }
test->bytes_sent += r; test->bytes_sent += r;
++test->blocks_sent;
if (test->settings->rate != 0 && test->settings->burst == 0) if (test->settings->rate != 0 && test->settings->burst == 0)
iperf_check_throttle(sp, &now); iperf_check_throttle(sp, &now);
if (multisend > 1 && test->settings->bytes != 0 && test->bytes_sent >= test->settings->bytes) if (multisend > 1 && test->settings->bytes != 0 && test->bytes_sent >= test->settings->bytes)
break; break;
if (multisend > 1 && test->settings->blocks != 0 && test->blocks_sent >= test->settings->blocks)
break;
} }
} }
} }
@ -872,6 +895,7 @@ iperf_recv(struct iperf_test *test, fd_set *read_setP)
return r; return r;
} }
test->bytes_sent += r; test->bytes_sent += r;
++test->blocks_sent;
FD_CLR(sp->socket, read_setP); FD_CLR(sp->socket, read_setP);
} }
} }
@ -1039,6 +1063,8 @@ send_parameters(struct iperf_test *test)
cJSON_AddIntToObject(j, "time", test->duration); cJSON_AddIntToObject(j, "time", test->duration);
if (test->settings->bytes) if (test->settings->bytes)
cJSON_AddIntToObject(j, "num", test->settings->bytes); cJSON_AddIntToObject(j, "num", test->settings->bytes);
if (test->settings->blocks)
cJSON_AddIntToObject(j, "blockcount", test->settings->blocks);
if (test->settings->mss) if (test->settings->mss)
cJSON_AddIntToObject(j, "MSS", test->settings->mss); cJSON_AddIntToObject(j, "MSS", test->settings->mss);
if (test->no_delay) if (test->no_delay)
@ -1097,6 +1123,8 @@ get_parameters(struct iperf_test *test)
test->duration = j_p->valueint; test->duration = j_p->valueint;
if ((j_p = cJSON_GetObjectItem(j, "num")) != NULL) if ((j_p = cJSON_GetObjectItem(j, "num")) != NULL)
test->settings->bytes = j_p->valueint; test->settings->bytes = j_p->valueint;
if ((j_p = cJSON_GetObjectItem(j, "blockcount")) != NULL)
test->settings->blocks = j_p->valueint;
if ((j_p = cJSON_GetObjectItem(j, "MSS")) != NULL) if ((j_p = cJSON_GetObjectItem(j, "MSS")) != NULL)
test->settings->mss = j_p->valueint; test->settings->mss = j_p->valueint;
if ((j_p = cJSON_GetObjectItem(j, "nodelay")) != NULL) if ((j_p = cJSON_GetObjectItem(j, "nodelay")) != NULL)
@ -1447,6 +1475,7 @@ iperf_defaults(struct iperf_test *testp)
testp->settings->burst = 0; testp->settings->burst = 0;
testp->settings->mss = 0; testp->settings->mss = 0;
testp->settings->bytes = 0; testp->settings->bytes = 0;
testp->settings->blocks = 0;
memset(testp->cookie, 0, COOKIE_SIZE); memset(testp->cookie, 0, COOKIE_SIZE);
testp->multisend = 10; /* arbitrary */ testp->multisend = 10; /* arbitrary */
@ -1591,6 +1620,7 @@ iperf_reset_test(struct iperf_test *test)
test->prot_listener = -1; test->prot_listener = -1;
test->bytes_sent = 0; test->bytes_sent = 0;
test->blocks_sent = 0;
test->reverse = 0; test->reverse = 0;
test->no_delay = 0; test->no_delay = 0;
@ -1620,6 +1650,7 @@ iperf_reset_stats(struct iperf_test *test)
struct iperf_stream_result *rp; struct iperf_stream_result *rp;
test->bytes_sent = 0; test->bytes_sent = 0;
test->blocks_sent = 0;
gettimeofday(&now, NULL); gettimeofday(&now, NULL);
SLIST_FOREACH(sp, &test->streams, streams) { SLIST_FOREACH(sp, &test->streams, streams) {
sp->omitted_packet_count = sp->packet_count; sp->omitted_packet_count = sp->packet_count;

Просмотреть файл

@ -244,6 +244,7 @@ enum {
IEUNIMP = 13, // Not implemented yet IEUNIMP = 13, // Not implemented yet
IEFILE = 14, // -F file couldn't be opened IEFILE = 14, // -F file couldn't be opened
IEBURST = 15, // Invalid burst count. Maximum value = %dMAX_BURST IEBURST = 15, // Invalid burst count. Maximum value = %dMAX_BURST
IEENDCONDITIONS = 16, // Only one test end condition (-t, -n, -k) may be specified
/* Test errors */ /* Test errors */
IENEWTEST = 100, // Unable to create a new test (check perror) IENEWTEST = 100, // Unable to create a new test (check perror)
IEINITTEST = 101, // Test initialization failed (check perror) IEINITTEST = 101, // Test initialization failed (check perror)

Просмотреть файл

@ -99,7 +99,7 @@ create_client_timers(struct iperf_test * test)
} }
cd.p = test; cd.p = test;
test->timer = test->stats_timer = test->reporter_timer = NULL; test->timer = test->stats_timer = test->reporter_timer = NULL;
if (test->settings->bytes == 0) { if (test->duration != 0) {
test->done = 0; test->done = 0;
test->timer = tmr_create(&now, test_timer_proc, cd, ( test->duration + test->omit ) * SEC_TO_US, 0); test->timer = tmr_create(&now, test_timer_proc, cd, ( test->duration + test->omit ) * SEC_TO_US, 0);
if (test->timer == NULL) { if (test->timer == NULL) {
@ -429,15 +429,10 @@ iperf_run_client(struct iperf_test * test)
} }
/* Is the test done yet? */ /* Is the test done yet? */
if (test->omitting) if ((!test->omitting) &&
continue; /* not done */ ((test->duration != 0 && test->done) ||
if (test->settings->bytes == 0) { (test->settings->bytes != 0 && test->bytes_sent >= test->settings->bytes) ||
if (!test->done) (test->settings->blocks != 0 && test->blocks_sent >= test->settings->blocks))) {
continue; /* not done */
} else {
if (test->bytes_sent < test->settings->bytes)
continue; /* not done */
}
/* Yes, done! Send TEST_END. */ /* Yes, done! Send TEST_END. */
test->done = 1; test->done = 1;
cpu_util(test->cpu_util); cpu_util(test->cpu_util);
@ -455,6 +450,7 @@ iperf_run_client(struct iperf_test * test)
} }
} }
} }
}
if (test->json_output) { if (test->json_output) {
if (iperf_json_finish(test) < 0) if (iperf_json_finish(test) < 0)

Просмотреть файл

@ -112,6 +112,9 @@ iperf_strerror(int i_errno)
case IEBURST: case IEBURST:
snprintf(errstr, len, "invalid burst count (maximum = %d)", MAX_BURST); snprintf(errstr, len, "invalid burst count (maximum = %d)", MAX_BURST);
break; break;
case IEENDCONDITIONS:
snprintf(errstr, len, "only one test end condition (-t, -n, -k) may be specified");
break;
case IENEWTEST: case IENEWTEST:
snprintf(errstr, len, "unable to create a new test"); snprintf(errstr, len, "unable to create a new test");
perr = 1; perr = 1;

Просмотреть файл

@ -89,6 +89,7 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
" (optional slash and packet count for burst mode)\n" " (optional slash and packet count for burst mode)\n"
" -t, --time # time in seconds to transmit for (default %d secs)\n" " -t, --time # time in seconds to transmit for (default %d secs)\n"
" -n, --num #[KMG] number of bytes to transmit (instead of -t)\n" " -n, --num #[KMG] number of bytes to transmit (instead of -t)\n"
" -k, --blockcount #[KMG] number of blocks (packets) to transmit (instead of -t or -n)\n"
" -l, --len #[KMG] length of buffer to read or write\n" " -l, --len #[KMG] length of buffer to read or write\n"
" (default %d KB for TCP, %d KB for UDP)\n" " (default %d KB for TCP, %d KB for UDP)\n"
" -P, --parallel # number of parallel client streams to run\n" " -P, --parallel # number of parallel client streams to run\n"
@ -177,6 +178,9 @@ const char test_start_time[] =
const char test_start_bytes[] = const char test_start_bytes[] =
"Starting Test: protocol: %s, %d streams, %d byte blocks, omitting %d seconds, %llu bytes to send\n"; "Starting Test: protocol: %s, %d streams, %d byte blocks, omitting %d seconds, %llu bytes to send\n";
const char test_start_blocks[] =
"Starting Test: protocol: %s, %d streams, %d byte blocks, omitting %d seconds, %d blocks to send\n";
/* ------------------------------------------------------------------- /* -------------------------------------------------------------------
* reports * reports

Просмотреть файл

@ -29,6 +29,7 @@ extern const char window_default[] ;
extern const char wait_server_threads[] ; extern const char wait_server_threads[] ;
extern const char test_start_time[]; extern const char test_start_time[];
extern const char test_start_bytes[]; extern const char test_start_bytes[];
extern const char test_start_blocks[];
extern const char report_time[] ; extern const char report_time[] ;
extern const char report_connecting[] ; extern const char report_connecting[] ;