nc6_test_master.c

来自「ecos实时嵌入式操作系统」· C语言 代码 · 共 834 行 · 第 1/2 页

C
834
字号
    int lost_packets = 0;    int conn_failures = 0;    int need_send, need_recv;    const char *type_name;    int pkt_ctr = 0;    unsigned char *dp;    need_recv = true;  need_send = true;  type_name = "TCP echo";    switch (type) {    case NC_REQUEST_TCP_RECV:        need_recv = false;        need_send = true;        type_name = "TCP recv";        break;    case NC_REQUEST_TCP_SEND:        need_recv = true;        need_send = false;        type_name = "TCP send";        break;    case NC_REQUEST_TCP_ECHO:        break;    }    new_test();    req.type = htonl(type);    req.nbufs = htonl(nbufs);    req.buflen = htonl(buflen);    req.slave_port = htonl(NC_TESTING_SLAVE_PORT);    req.master_port = htonl(NC_TESTING_MASTER_PORT);    nc_message(s1, &req, &reply, slave);    if (reply.response != ntohl(NC_REPLY_ACK)) {        test_printf("Slave denied %s [%d,%d] test\n", type_name, nbufs, buflen);        return;    }    s = socket(slave->sa_family, SOCK_STREAM, 0);    if (s < 0) {        pexit("datagram socket");    }    test_printf("Start %s [%d,%d]", type_name, nbufs, buflen);    if (pause_time) {        test_printf(" - %dms delay after %d packet%s\n", pause_time*10,                     pause_threshold, pause_threshold > 1 ? "s" : "");    } else {        test_printf(" - no delays\n");    }    test_delay(3*100);      memcpy(&test_chan_slave, slave, sa_len(slave));    switch (slave->sa_family) {    case AF_INET:        ((struct sockaddr_in *)&test_chan_slave)->sin_port = htons(ntohl(req.slave_port));        break;    case AF_INET6:        ((struct sockaddr_in6 *)&test_chan_slave)->sin6_port = htons(ntohl(req.slave_port));        break;    default:        pexit("strange TCP sockaddr");    }    while (connect(s, (struct sockaddr *)&test_chan_slave, sa_len(slave)) < 0) {         perror("Can't connect to slave");        if (++conn_failures > MAX_ERRORS) {            test_printf("Too many connection failures - giving up\n");            return;        }        if (errno == ECONNREFUSED) {            // Give the slave a little time            test_delay(100);  // 1 second        } else {            return;        }    }    gettimeofday(&start_time, 0);    seq = 0;  seq_errors = 0;  total_packets = 0;    for (i = 0;  i < nbufs;  i++) {        td_len = buflen + sizeof(struct nc_test_data);        if (need_send) {            tdp = (struct nc_test_data *)out_buf;            tdp->key1 = htonl(NC_TEST_DATA_KEY1);            tdp->key2 = htonl(NC_TEST_DATA_KEY2);            tdp->seq = htonl(i);            tdp->len = htonl(td_len);            tot_len = 0;            dp = (unsigned char *)tdp;            while (tot_len < td_len) {                len = td_len - tot_len;                if ((wlen = write(s, dp, len)) != len) {                    if (wlen < 0) {                        test_printf("Slave connection broken\n");                        perror("write");                        close(s);                        return;                    } else {                        test_printf("block: %d, short write - only %d of %d\n",                                     total_packets, wlen, len);                    }                }                tot_len += wlen;                dp += wlen;            }            total_packets++;        }        if (need_recv) {            tdp = (struct nc_test_data *)in_buf;            res = do_read(s, tdp, td_len);            if (res != td_len) {                lost_packets++;                if (res < 0) {                    test_printf("Slave connection broken\n");                    perror("read");                    break;                } else {                    test_printf("Slave timed out after %d buffers [read %d bytes]\n", i, res);                }            } else {                if ((ntohl(tdp->key1) == NC_TEST_DATA_KEY1) &&                    (ntohl(tdp->key2) == NC_TEST_DATA_KEY2)) {                    if (ntohl(tdp->seq) != seq) {                        test_printf("Packets out of sequence - recvd: %d, expected: %d\n",                                    ntohl(tdp->seq), seq);                        seq_errors++;                        if (!need_send) {                            // Reset sequence to what the slave wants                            seq = ntohl(tdp->seq);                        }                    }                } else {                    test_printf("Bad data packet - key: %x/%x, seq: %d\n",                                ntohl(tdp->key1), ntohl(tdp->key2),                                ntohl(tdp->seq));                }                total_packets++;            }            seq++;            if (seq == nbufs) {                break;            }            if (pause_time && (++pkt_ctr == pause_threshold)) {                pkt_ctr = 0;                test_delay(pause_time);            }        }    }    gettimeofday(&end_time, 0);    show_results(type_name, &start_time, &end_time, total_packets, buflen,                  lost_packets, seq_errors);    // Fetch results record    if (do_read(s, &results, sizeof(results)) != sizeof(results)) {        test_printf("No results record sent\n");    } else {        show_test_results(&results);    }    close(s);}intdo_set_load(int s, struct sockaddr *slave, int load_level){    struct nc_request req;    struct nc_reply reply;    req.type = htonl(NC_REQUEST_SET_LOAD);    req.nbufs = htonl(load_level);    nc_message(s, &req, &reply, slave);    return (reply.response == ntohl(NC_REPLY_ACK));}intdo_start_idle(int s, struct sockaddr *slave){    struct nc_request req;    struct nc_reply reply;    req.type = htonl(NC_REQUEST_START_IDLE);    nc_message(s, &req, &reply, slave);    return (reply.response == ntohl(NC_REPLY_ACK));}voiddo_stop_idle(int s, struct sockaddr *slave, int calibrate){    struct nc_request req;    struct nc_reply reply;    long long res_idle_count;    long long adj_count;    int idle, res_idle_ticks;    req.type = htonl(NC_REQUEST_STOP_IDLE);    nc_message(s, &req, &reply, slave);    if (reply.response == ntohl(NC_REPLY_ACK)) {        res_idle_ticks = ntohl(reply.misc.idle_results.elapsed_time);        res_idle_count = ((long long)ntohl(reply.misc.idle_results.count[0]) << 32) |            ntohl(reply.misc.idle_results.count[1]);        test_printf("IDLE - ticks: %d, count: %ld",                     res_idle_ticks, res_idle_count);        if (calibrate) {            idle_count = res_idle_count;            idle_ticks = res_idle_ticks;        } else {            adj_count = res_idle_count / res_idle_ticks;            adj_count *= idle_ticks;            idle = (int) ((adj_count * 100) / idle_count);            test_printf(", %d%% idle", idle);        }        test_printf("\n");    } else {        test_printf("Slave failed on IDLE\n");    }}voiddo_disconnect(int s, struct sockaddr *slave){    struct nc_request req;    struct nc_reply reply;    req.type = htonl(NC_REQUEST_DISCONNECT);    nc_message(s, &req, &reply, slave);}static voidnc_master_test(struct sockaddr *slave, int test_tcp, int test_udp,               int test_slave_loads, int test_master_loads){    int s, i;    struct sockaddr_storage my_addr;    struct pause pause_times[] = {        {0,0}, {1,10}, {5,10}, {10,10}, {1,1} };    s = socket(slave->sa_family, SOCK_DGRAM, 0);    if (s < 0) {        pexit("datagram socket");    }    memset(&my_addr, 0, sizeof(my_addr));    ((struct sockaddr *)&my_addr)->sa_family = slave->sa_family;#ifndef __linux    ((struct sockaddr *)&my_addr)->sa_len = slave->sa_len;#endif    switch (slave->sa_family) {    case AF_INET:        ((struct sockaddr_in *)&my_addr)->sin_addr.s_addr = htonl(INADDR_ANY);        ((struct sockaddr_in *)&my_addr)->sin_port = htons(NC_MASTER_PORT);        break;    case AF_INET6:        ((struct sockaddr_in6 *)&my_addr)->sin6_addr = in6addr_any;        ((struct sockaddr_in6 *)&my_addr)->sin6_port = htons(NC_MASTER_PORT);        break;    default:        pexit("strange sockaddr family");    }    if (bind(s, (struct sockaddr *) &my_addr, sa_len((struct sockaddr *)&my_addr)) < 0) {        pexit("UDP bind <main>");    }    test_printf("================== No load, master at 100%% ========================\n");    if (test_udp) {        do_udp_test(s, NC_REQUEST_UDP_ECHO, slave, 640, 1024, 0, 0);        do_udp_test(s, NC_REQUEST_UDP_SEND, slave, 640, 1024, 0, 0);        do_udp_test(s, NC_REQUEST_UDP_RECV, slave, 640, 1024, 0, 0);    }    if (test_tcp) {        do_tcp_test(s, NC_REQUEST_TCP_ECHO, slave, 640, 1024, 0, 0);        do_tcp_test(s, NC_REQUEST_TCP_SEND, slave, 640, 1024, 0, 0);        do_tcp_test(s, NC_REQUEST_TCP_RECV, slave, 640, 1024, 0, 0);        do_tcp_test(s, NC_REQUEST_TCP_ECHO, slave, 64, 10240, 0, 0);    }    if (test_slave_loads) {        if (do_set_load(s, slave, 0)) {            test_printf("\n====================== Various slave compute loads ===================\n");            for (i = 0;  i < 60;  i += 10) {                test_printf(">>>>>>>>>>>> slave processing load at %d%%\n", i);                                do_set_load(s, slave, i);                if (test_udp) {                    do_udp_test(s, NC_REQUEST_UDP_ECHO, slave, 2048, 1024, 0, 0);                }                if (test_tcp) {                    do_tcp_test(s, NC_REQUEST_TCP_ECHO, slave, 2048, 1024, 0, 0);                }            }        }    }    if (test_master_loads) {        if (do_start_idle(s, slave)) {            test_printf("\n====================== Various master loads ===================\n");            test_printf("Testing IDLE for %d seconds\n", IDLE_TEST_TIME);            test_delay(IDLE_TEST_TIME*100);            do_stop_idle(s, slave, true);            for (i = 0;  i < LENGTH(pause_times);  i++) {                if (test_udp) {                    do_start_idle(s, slave);                    do_udp_test(s, NC_REQUEST_UDP_ECHO, slave, 2048, 1024,                                 pause_times[i].pause_ticks, pause_times[i].pause_threshold);                    do_stop_idle(s, slave, false);                }                if (test_tcp) {                    do_start_idle(s, slave);                    do_tcp_test(s, NC_REQUEST_TCP_ECHO, slave, 2048, 1024,                                 pause_times[i].pause_ticks, pause_times[i].pause_threshold);                    do_stop_idle(s, slave, false);                }            }        }    }//    do_disconnect(s, slave);    close(s);}static voidnc_master(struct test_params *p){    struct sockaddr_storage slave, my_addr;    struct addrinfo *ai, *addrs, hints;    char *host = (char *)NULL;    int i;    int err = 0;    int test_tcp = true;    int test_udp = true;    int test_slave_loads = true;    int test_master_loads = true;    for (i = 1;  i < p->argc;  i++) {        if (p->argv[i][0] == '-') {            switch (p->argv[i][1]) {            case 't':                test_tcp = false;                break;            case 'u':                test_udp = false;                break;            case 's':                test_slave_loads = false;                break;            case 'm':                test_master_loads = false;                break;            default:                test_printf("... invalid switch '%s'\n", p->argv[i]);                err++;            }        } else {            if (host != (char *)NULL) {                test_printf("... ignoring argument '%s'\n", p->argv[i]);                err++;            } else {                host = p->argv[i];            }        }    }    if ((err != 0) || (p->argc < 2) || (host == (char *)NULL)) {        test_printf("usage: 'master <host> [-t] [-u] [-s] [-m]'\n");        test_printf("   -t - suppress TCP tests\n");        test_printf("   -u - suppress UDP tests\n");        test_printf("   -s - suppress slave load tests\n");        test_printf("   -m - suppress master load tests\n");        return;    }    bzero(&hints, sizeof(hints));    hints.ai_family = PF_UNSPEC;    hints.ai_socktype = SOCK_DGRAM;    hints.ai_flags = AI_PASSIVE;    if ((err = getaddrinfo(p->argv[1], _string(NC_SLAVE_PORT), &hints, &addrs)) != EAI_NONE) {        test_printf("<ERROR> can't getaddrinfo(): %s\n", gai_strerror(err));        pexit("getaddrinfo");    }    // Prepare a socket for each connection type    ai = addrs;    while (ai) {        nc_master_test(ai->ai_addr, test_tcp, test_udp, test_slave_loads, test_master_loads);        ai = ai->ai_next;    }}voidnet_test(test_param_t p){    test_printf("Start Network Characterization - MASTER\n");#ifdef __ECOS    init_all_network_interfaces();#endif    nc_master((struct test_params *)p);    cyg_test_exit();}#ifdef __ECOSvoidcyg_start(void){    static struct test_params p;    // Create a main thread, so we can run the scheduler and have time 'pass'    cyg_thread_create(10,                // Priority - just a number                      net_test,          // entry                      (cyg_addrword_t)&p,// entry parameter                      "Network test",    // Name                      &stack[0],         // Stack                      STACK_SIZE,        // Size                      &thread_handle,    // Handle                      &thread_data       // Thread data structure            );    cyg_thread_resume(thread_handle);  // Start it    cyg_scheduler_start();}#elseintmain(int argc, char *argv[]){    struct test_params p;    p.argc = argc;    p.argv = argv;    net_test(&p);}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?