Iperf results are now exchanged between client and server. The server also now prints results.

This commit is contained in:
sethdelliott 2010-06-29 22:02:30 +00:00
parent 43bcc9709c
commit 181d61afab
5 changed files with 152 additions and 42 deletions

View File

@ -212,8 +212,9 @@ enum
CREATE_STREAMS = 12,
SERVER_TERMINATE = 13,
CLIENT_TERMINATE = 14,
DISPLAY_RESULTS = 15,
IPERF_DONE = 16,
EXCHANGE_RESULTS = 15,
DISPLAY_RESULTS = 16,
IPERF_DONE = 17,
ACCESS_DENIED = -1,
};

View File

@ -359,7 +359,7 @@ iperf_exchange_parameters(struct iperf_test * test)
parse_parameters(test);
printf("test cookie: %s\n", test->default_settings->cookie);
printf(" cookie: %s\n", test->default_settings->cookie);
test->prot_listener = netannounce(test->protocol, NULL, test->server_port + 1);
FD_SET(test->prot_listener, &test->read_set);
@ -383,52 +383,140 @@ iperf_exchange_parameters(struct iperf_test * test)
int
iperf_exchange_results(struct iperf_test *test)
{
size_t size = 0;
unsigned int size;
char buf[32];
char *rbuf;
char *results;
struct iperf_stream *sp;
rbuf = (char *) malloc(5*sizeof(char));
if (rbuf == NULL) {
perror("malloc results");
return -1;
}
results = rbuf + 4;
*results = '\0';
iperf_size_t bytes_transferred;
if (test->role == 'c') {
/* Prepare results string and send to server */
results = NULL;
size = 0;
for (sp = test->streams; sp; sp = sp->next) {
snprintf(buf, 32, "%d:%llu\n", sp->id, sp->result->bytes_sent);
bytes_transferred = (test->reverse ? sp->result->bytes_received : sp->result->bytes_sent);
snprintf(buf, 32, "%d:%llu\n", sp->id, bytes_transferred);
size += strlen(buf);
if ((rbuf = realloc(rbuf, size+5)) == NULL) {
if ((results = realloc(results, size+1)) == NULL) {
perror("realloc results");
return -1;
}
if (sp == test->streams)
*results = '\0';
strncat(results, buf, size+1);
}
size++;
size = htonl(size);
memcpy(rbuf, &size, sizeof(size));
if (Nwrite(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) {
perror("Nwrite size");
return (-1);
}
if (Nwrite(test->ctrl_sck, results, ntohl(size), Ptcp) < 0) {
perror("Nwrite results");
return (-1);
}
free(results);
/* Get server results string */
if (Nread(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) {
perror("Nread size");
return (-1);
}
size = ntohl(size);
results = (char *) malloc(size * sizeof(char));
if (results == NULL) {
perror("malloc results");
return (-1);
}
if (Nread(test->ctrl_sck, results, size, Ptcp) < 0) {
perror("Nread results");
return (-1);
}
parse_results(test, results);
free(results);
} else {
/* Get client results string */
if (Nread(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) {
perror("Nread size");
return (-1);
}
size = ntohl(size);
results = (char *) malloc(size * sizeof(char));
if (results == NULL) {
perror("malloc results");
return (-1);
}
if (Nread(test->ctrl_sck, results, size, Ptcp) < 0) {
perror("Nread results");
return (-1);
}
parse_results(test, results);
free(results);
/* Prepare results string and send to client */
results = NULL;
size = 0;
for (sp = test->streams; sp; sp = sp->next) {
snprintf(buf, 32, "%d:%llu\n", sp->id, sp->result->bytes_received);
bytes_transferred = (test->reverse ? sp->result->bytes_sent : sp->result->bytes_received);
snprintf(buf, 32, "%d:%llu\n", sp->id, bytes_transferred);
size += strlen(buf);
if ((rbuf = realloc(rbuf, size+5)) == NULL) {
if ((results = realloc(results, size+1)) == NULL) {
perror("realloc results");
return (-1);
}
if (sp == test->streams)
*results = '\0';
strncat(results, buf, size+1);
}
size++;
size = htonl(size);
memcpy(rbuf, &size, sizeof(size));
}
if (Nwrite(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) {
perror("Nwrite size");
return (-1);
}
if (Nwrite(test->ctrl_sck, results, ntohl(size), Ptcp) < 0) {
perror("Nwrite results");
return (-1);
}
free(results);
free(rbuf);
}
return 0;
}
/*************************************************************/
int
parse_results(struct iperf_test *test, char *results)
{
int sid;
char *word;
struct iperf_stream *sp;
iperf_size_t bytes_transferred;
for (word = strtok(results, "\n:"); word; word = strtok(NULL, "\n:")) {
sid = atoi(word);
bytes_transferred = atoll(strtok(NULL, "\n:"));
for (sp = test->streams; sp; sp = sp->next)
if (sp->id == sid) break;
if (sp == NULL) {
fprintf(stderr, "error: No stream with id %d\n", sid);
return (-1);
}
if ((test->role == 'c' && !test->reverse) || (test->role == 's' && test->reverse))
sp->result->bytes_received = bytes_transferred;
else
sp->result->bytes_sent = bytes_transferred;
}
return 0;
}
/*************************************************************/
@ -627,6 +715,9 @@ iperf_handle_message_client(struct iperf_test *test)
break;
case TEST_END:
break;
case EXCHANGE_RESULTS:
iperf_exchange_results(test);
break;
case DISPLAY_RESULTS:
iperf_client_end(test);
break;
@ -750,8 +841,6 @@ iperf_stats_callback(struct iperf_test * test)
/**
* iperf_reporter_callback -- handles the report printing
*
*returns report
* XXX: This function needs to be updated to reflect the new code
*/
void
@ -761,7 +850,8 @@ iperf_reporter_callback(struct iperf_test * test)
char ubuf[UNIT_LEN];
char nbuf[UNIT_LEN];
struct iperf_stream *sp = NULL;
iperf_size_t bytes = 0, total_bytes = 0;
iperf_size_t bytes = 0, bytes_sent = 0, bytes_received = 0;
iperf_size_t total_sent = 0, total_received = 0;
double start_time, end_time;
struct iperf_interval_results *ip = NULL;
@ -800,24 +890,23 @@ iperf_reporter_callback(struct iperf_test * test)
case DISPLAY_RESULTS:
/* print final summary for all intervals */
iperf_exchange_results(test);
start_time = 0.;
sp = test->streams;
end_time = timeval_diff(&sp->result->start_time, &sp->result->end_time);
for (sp = test->streams; sp != NULL; sp = sp->next) {
if (test->role == 'c')
bytes = sp->result->bytes_sent;
else
bytes = sp->result->bytes_received;
total_bytes += bytes;
bytes_sent = sp->result->bytes_sent;
bytes_received = sp->result->bytes_received;
total_sent += bytes_sent;
total_received += bytes_received;
if (test->protocol == Pudp) {
total_packets += sp->packet_count;
lost_packets += sp->cnt_error;
}
if (bytes > 0 ) {
unit_snprintf(ubuf, UNIT_LEN, (double) (bytes), 'A');
unit_snprintf(nbuf, UNIT_LEN, (double) (bytes / end_time), test->default_settings->unit_format);
if (bytes_sent > 0) {
unit_snprintf(ubuf, UNIT_LEN, (double) (bytes_sent), 'A');
unit_snprintf(nbuf, UNIT_LEN, (double) (bytes_sent / end_time), test->default_settings->unit_format);
if (test->protocol == Ptcp) {
printf(report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf);
@ -838,13 +927,24 @@ iperf_reporter_callback(struct iperf_test * test)
printf(report_sum_outoforder, start_time, end_time, sp->cnt_error);
}
}
if (bytes_received > 0) {
unit_snprintf(ubuf, UNIT_LEN, (double) bytes_received, 'A');
unit_snprintf(nbuf, UNIT_LEN, (double) (bytes_received / end_time), test->default_settings->unit_format);
if (test->protocol == Ptcp) {
printf(report_bw_format, sp->socket, start_time, end_time, ubuf, nbuf);
}
}
}
unit_snprintf(ubuf, UNIT_LEN, (double) total_bytes, 'A');
unit_snprintf(nbuf, UNIT_LEN, (double) total_bytes / end_time, test->default_settings->unit_format);
if (test->num_streams > 1) {
unit_snprintf(ubuf, UNIT_LEN, (double) total_sent, 'A');
unit_snprintf(nbuf, UNIT_LEN, (double) total_sent / end_time, test->default_settings->unit_format);
if (test->protocol == Ptcp) {
printf("[MSG] Total sent\n");
printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf);
unit_snprintf(ubuf, UNIT_LEN, (double) total_received, 'A');
unit_snprintf(nbuf, UNIT_LEN, (double) (total_received / end_time), test->default_settings->unit_format);
printf("[MSG] Total received\n");
printf(report_sum_bw_format, start_time, end_time, ubuf, nbuf);
} else {
printf(report_sum_bw_jitter_loss_format, start_time, end_time, ubuf, nbuf, sp->jitter,
@ -989,16 +1089,17 @@ iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp)
int
iperf_add_stream(struct iperf_test * test, struct iperf_stream * sp)
{
int i;
struct iperf_stream *n;
if (!test->streams) {
test->streams = sp;
sp->id = 1;
return 1;
} else {
n = test->streams;
while (n->next)
n = n->next;
for (n = test->streams, i = 2; n->next; n = n->next, ++i);
n->next = sp;
sp->id = i;
return 1;
}

View File

@ -130,6 +130,8 @@ int package_parameters(struct iperf_test *);
int parse_parameters(struct iperf_test *);
int iperf_create_streams(struct iperf_test *);
int iperf_handle_message_client(struct iperf_test *);
int iperf_exchange_results(struct iperf_test *);
int parse_results(struct iperf_test *, char *);
#endif

View File

@ -154,11 +154,18 @@ iperf_handle_message_server(struct iperf_test *test)
case TEST_RUNNING:
break;
case TEST_END:
test->state = EXCHANGE_RESULTS;
if (write(test->ctrl_sck, &test->state, sizeof(char)) < 0) {
perror("write EXCHANGE_RESULTS");
exit(1);
}
iperf_exchange_results(test);
test->state = DISPLAY_RESULTS;
if (write(test->ctrl_sck, &test->state, sizeof(char)) < 0) {
perror("write DISPLAY_RESULTS");
exit(1);
}
test->reporter_callback(test);
break;
case IPERF_DONE:
break;
@ -202,8 +209,6 @@ iperf_run_server(struct iperf_test *test)
test->default_settings->state = TEST_RUNNING;
printf("iperf_run_server: Waiting for client connect.... \n");
while (test->state != IPERF_DONE) {
// XXX: Move test->temp_set over to local fd_set

View File

@ -162,6 +162,7 @@ iperf_tcp_accept(struct iperf_test * test)
// XXX: Nonblocking off. OKAY since we use select.
// setnonblocking(peersock);
// XXX: This doesn't fit our API model!
sp = test->new_stream(test);
sp->socket = peersock;
iperf_init_stream(sp, test);