IP_STATIC
IPCOM_PROCESS( ipcom_cmd_smptest_client_spawn )
{
    union
    {
        struct Ip_sockaddr          sa;
#ifdef IPCOM_USE_INET6
        struct Ip_sockaddr_in6      sin6;
#endif
        struct Ip_sockaddr_storage  ss;
        struct Ip_sockaddr_in       sin;
    } addr;
    Ip_fd socket;
    unsigned char *buf = 0;
    int portadd = spawn_number_client++;
    int opt_val = 1;
    int sec = SECONDS_CLIENT;
    int send = 0;
    int num_sends = 0;
    unsigned long num_bytes = 0;

    ipcom_proc_init();

    ipcom_memset( &addr.ss, 0, sizeof( addr.ss ) );
    ipcom_memcpy( &addr.sa, smp_opt_client.res->ai_addr, smp_opt_client.res->ai_addrlen );

    socket = ipcom_socket( smp_opt_client.res->ai_family, smp_opt_client.res->ai_socktype, smp_opt_client.res->ai_protocol );
    if (socket == IP_SOCKERR)
    {
        ipcom_printf("Failed to create socket for thread %d: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno));
        return_client = 1;
        ipcom_sem_post( sem_wait_client );
        return;
    }

    if ( 0 != ipcom_setsockopt(socket, IP_SOL_SOCKET, IP_SO_REUSEPORT, &opt_val, sizeof (opt_val)) )
    {
        ipcom_printf("ipcom_setsockopt failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return_client = 1;
        ipcom_sem_post( sem_wait_client );
        return;
    }

    if ( 0 != ipcom_socketioctl( socket, IP_X_SIOCSINTR, &sec ) )
    {
        ipcom_printf("ipcom_socketioctl failed: %s"IP_LF, ipcom_strerror(ipcom_errno));
        return_client = 1;
        ipcom_sem_post( sem_wait_client );
        return;
    }

    addr.sin.sin_port = ip_htons( smp_opt_client.port + portadd );   /* port is in the same place for IPv4 and IPv6 */
    if ( smp_opt_client.tcp )
    {
        if ( 0 != ipcom_connect( socket, &addr.sa, smp_opt_client.res->ai_addrlen ) )
        {
            ipcom_printf("Thread %d failed to connect: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno));
            return_client = 1;
            ipcom_sem_post( sem_wait_client );
            return;
        }
        if ( verbose )
            ipcom_printf("Thread %d connected to port %d"IP_LF, portadd, smp_opt_client.port + portadd );
    }

    buf = ipcom_malloc( smp_opt_client.num_bytes );
    while ( 1 )
    {
        if ( smp_opt_client.tcp )
            send = ipcom_send( socket, buf, smp_opt_client.num_bytes, 0);
        else
            send = ipcom_sendto( socket, buf, smp_opt_client.num_bytes, 0, &addr.sa, smp_opt_client.res->ai_addrlen );

        if ( send > 0 )
           num_bytes += send;
        num_sends++;
        if ( send == 0 )
        {
           ipcom_printf( "Error: Disconnected"IP_LF );
           return_client = 1;
           break;
        }
        else if ( send < 0 )
        {
            if ( ipcom_errno == IP_ERRNO_EINTR )
            {
                if ( verbose )
                {
                    ipcom_printf("Thread %d done."IP_LF, portadd );
                    ipcom_printf("  Sends: %d"IP_LF, num_sends );
                    ipcom_printf("  MB/s:  %f"IP_LF, ((float)(num_bytes)/(1024.0f*1024.0f) )/5.0f );
                }
                break;
            }
            return_client = 1;
            ipcom_printf("Error on thread %d: %s"IP_LF, portadd, ipcom_strerror(ipcom_errno));
            break;
        }
    }

    if ( verbose )
    {
        if ( spawn_number_client != smp_opt_client.num_sock )
        {
            ipcom_printf("Error. Only %d client-sockets seemed to work."IP_LF, spawn_number_client );
        }
    }

    ipcom_socketclose( socket );

    ipcom_free( buf );
    if ( 0 == ipcom_atomic_sub_and_return( &num_wait_client, 1 ) )
        ipcom_sem_post( sem_wait_client );

    ipcom_proc_exit();
}
示例#2
0
/*
 *===========================================================================
 *                    ipcom_cmd_sockperf_run
 *===========================================================================
 * Description: Sends/receives data.
 * Parameters:
 * Returns:
 */
IP_STATIC void
ipcom_cmd_sockperf_run(Ipcom_cmd_sockperf_t *cmd)
{
    struct Ip_timeval  tmo = { 0, 0 };
    struct Ip_timeval *ptmo;
    struct Ip_timeval  start;
    struct Ip_timeval  stop;
    Ip_u32             i;
    Ip_u32             c;
    int                num_ready;
    Ip_fd             *s = cmd->sock_array;
    Ip_u32             total_bytes_to_send = cmd->num_buf * cmd->buf_len;
    Ip_u32             finished_sockets = 0;
    Ip_u32             total_bytes_read = 0;
    Ip_ssize_t         bytes;
    Ip_fd_set          read_set;
    int                send_flags = (cmd->transmit && cmd->receive) ? IP_MSG_DONTWAIT : 0;

    if (cmd->transmit)
        ipcom_printf("sockperf-t: send buffer is %u"IP_LF, cmd->sendbuf_size);
    if (cmd->receive)
        ipcom_printf("sockperf-r: receive buffer is %u"IP_LF, cmd->sendbuf_size);
    for (i = 0; i < cmd->num_sock; i++)
    {
        int on = 1;

        if (ipcom_setsockopt(s[i],
                             IP_SOL_SOCKET,
                             IP_SO_REUSEADDR,
                             &on,
                             sizeof(on)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt IP_SO_REUSEADDR failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return;
        }

        if (ipcom_setsockopt(s[i],
                             IP_SOL_SOCKET,
                             IP_SO_SNDBUF,
                             &cmd->sendbuf_size,
                             sizeof(cmd->sendbuf_size)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt IP_SO_SNDBUF failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return;
        }

        if (ipcom_setsockopt(s[i],
                             IP_SOL_SOCKET,
                             IP_SO_RCVBUF,
                             &cmd->recvbuf_size,
                             sizeof(cmd->recvbuf_size)) < 0)
        {
            ipcom_printf("sockperf-c: setsockopt IP_SO_SNDBUF failed : %s"IP_LF,
                         ipcom_strerror(ipcom_errno));
            return;
        }
    }


    if (cmd->receive)
    {
        IP_FD_ZERO(&cmd->read_set);
        cmd->width = s[0];
        IP_FD_SET(s[0], &cmd->read_set);
        for (i = 1; i < cmd->num_sock; i++)
            if (s[i] != IP_INVALID_SOCKET)
            {
                cmd->width = IP_MAX(cmd->width, s[i]);
                IP_FD_SET(s[i], &cmd->read_set);
            }
    }

    ipcom_microtime(&start);
    while ((cmd->transmit && total_bytes_to_send)
           || (cmd->receive && finished_sockets < cmd->num_sock))
    {
        if (cmd->transmit && total_bytes_to_send)
        {
            for (i = 0; i < cmd->num_sock; i++)
            {
                if (cmd->testpattern)
                {
                    /* Test patter is "[B|E|D]xxxxxx ", B = first 8 byte in buffer, E = last 8 bytes, D = all other */
                    for (c = 0; c < cmd->buf_len; c += 8)
                        ipcom_sprintf(cmd->buf + c, "%c%06ld ",
                                      c == 0 ? '>' : (c >= cmd->buf_len - 8 ? '<' : '#'),
                                      cmd->send_pattern[i]++ % 1000000);
                }

                bytes = ipcom_send(s[i],
                                   cmd->buf,
                                   IP_MIN(cmd->buf_len, total_bytes_to_send),
                                   send_flags);
                if (bytes < 0 && ipcom_errno == IP_ERRNO_EWOULDBLOCK)
                    (void)ipcom_sleep(0);
                else
                {
                    if (bytes < 0)
                    {
                        ipcom_printf("sockperf-t: send failed : %s"IP_LF,
                                     ipcom_strerror(ipcom_errno));
                        return;
                    }
                    total_bytes_to_send -= bytes;
                }
            }

            if (cmd->receive && total_bytes_to_send == 0)
                for (i = 0; i < cmd->num_sock; i++)
                    if (ipcom_shutdown(s[i], IP_SHUT_WR) < 0)
                    {
                        ipcom_printf("sockperf-t: shutdown failed: %s"IP_LF,
                                     ipcom_strerror(ipcom_errno));
                        return;
                    }
        }

        if (cmd->receive)
        {
            ptmo = IP_NULL;
            while (finished_sockets < cmd->num_sock)
            {
                read_set = cmd->read_set;
                num_ready = ipcom_socketselect(cmd->width + 1, &read_set, IP_NULL, IP_NULL, ptmo);

                if (num_ready == 0)
                    break;

                if (num_ready < 0)
                {
                    ipcom_printf("sockperf-r: select failed: %s"IP_LF,
                                 ipcom_strerror(ipcom_errno));
                    return;
                }

                for (i = 0; i < cmd->num_sock; i++)
                {
                    if (IP_FD_ISSET(s[i], &read_set))
                    {
                        bytes = ipcom_recv(s[i], cmd->buf, cmd->buf_len, 0);
                        if (bytes < 0)
                        {
                            ipcom_printf("sockperf-r: recv failed: %s"IP_LF,
                                         ipcom_strerror(ipcom_errno));
                            return;
                        }

                        if (cmd->testpattern)
                        {
                            if (cmd->echo)
                                ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, cmd->recv_pattern[i]);
                            for (c = 0; c < (Ip_u32)bytes; c += 8)
                            {
                                if (cmd->buf[c] != '#' && cmd->buf[c] != '>' && cmd->buf[c] != '<')
                                {
                                    ipcom_printf("\nsockperf-r: test pattern error, expected B, D or E found %c(%d) offset %ld"IP_LF,
                                                 cmd->buf[c], (int)cmd->buf[c], c);
                                    ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, 0);
                                    return;
                                }

                                if (ipcom_atoi(cmd->buf + c + 1) != (int)(cmd->recv_pattern[i]++ % 1000000))
                                {
                                    ipcom_printf("\nsockperf-r: test pattern error, was %d should be %ld offset %ld"IP_LF,
                                                 ipcom_atoi(cmd->buf + c + 1), (cmd->recv_pattern[i] - 1) % 1000000, c);
                                    ipcom_cmd_sockperf_echo_buf(cmd->buf, bytes, 0);
                                    return;
                                }
                            }
                        }

                        if (bytes > 0)
                            total_bytes_read += bytes;
                        else
                        {
                            finished_sockets++;
                            IP_FD_CLR(s[i], &cmd->read_set);
                        }
                    }
                }

                if (cmd->transmit && total_bytes_to_send)
                    ptmo = &tmo;
            }
        }
    }
    ipcom_microtime(&stop);

    if (cmd->transmit)
        ipcom_printf("sockperf-t: %lu bytes sent in %ld ms (%lu kbyte/s)"IP_LF,
                     cmd->num_buf * cmd->buf_len,
                     ipcom_cmd_sockperf_tv_to_msec(&start, &stop),
                     cmd->num_buf * cmd->buf_len / (Ip_u32)ipcom_cmd_sockperf_tv_to_msec(&start, &stop) * 1000 / 1024);
    if (cmd->receive)
        ipcom_printf("sockperf-r: %lu bytes read in %ld ms (%lu kbyte/s)"IP_LF,
                     total_bytes_read,
                     ipcom_cmd_sockperf_tv_to_msec(&start, &stop),
                     total_bytes_read / (Ip_u32)ipcom_cmd_sockperf_tv_to_msec(&start, &stop) * 1000 / 1024);

}