performance/udpsclient.c
///////////////////////////////////////////////////////////////////////////////
// Filename: udpsclient.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: measure performance of UDP (this file: UDP client) (socket version)
//          needs udpsserver(.c) as UDP server
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/03/01 17:56:03 muellerg: created
//
///////////////////////////////////////////////////////////////////////////////
// Feature test switches ///////////////////////////// Feature test switches //
    /* NONE */
// System headers /////////////////////////////////////////// System headers //
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#ifndef sun
#include <strings.h>
#endif
#include <unistd.h>
// Local headers ///////////////////////////////////////////// Local headers //
#include "../common.h"
#include "udps.h"
// Macros /////////////////////////////////////////////////////////// Macros //
    /* NONE */
// File scope objects /////////////////////////////////// File scope objects //
    /* NONE */
// External variables, functions, and classes ///////////// External objects //
    /* NONE */
// Signal catching functions ///////////////////// Signal catching functions //
    /* NONE */
// Structures, unions, and class definitions /////////////////// Definitions //
    /* NONE */
// Functions and class implementation /// Functions and class implementation //
/*
 * send data to UDP server and measure time
 *
 * in: sockfd:     fd to use
 *     pserv_addr: ptr to appropriate sockaddr_XX structure
 *     servlen:    actual sizeof(*pserv_addr)
 */
void do_it(char *name, int sockfd, struct sockaddr *pserv_addr, int servlen)
{
    int     size, i, n;
    char *mesg;             
    mesg = new char[MAX_BUFFER];
    // measure throughput
    measurement mes(name, "mes", max_measurement);
    
    for(size=1; size <= max_size; size*=2)  
    {
        mes.start(size, NUMBER_REPEAT);
        for(i=0; i < NUMBER_REPEAT; i++)
        {
            if (sendto(sockfd, mesg, size, 0, pserv_addr, servlen) != size)
                    error.system("sendto error");
            // get acknowledgment
            n = recvfrom(sockfd, mesg, MAX_BUFFER, 0,
                    (struct sockaddr *) 0, (int *) 0);
            if (n < 0)
                error.system("recvfrom error");
        }
        mes.end();
    }
    // measure difference in speed
    measurement mes2(name, "mes2", NUMBER_REPEAT);
    
    size = 4;       // one long word
    for(i=0; i < NUMBER_REPEAT; i++)
    {
        mes2.start(-1, 0);
        if (sendto(sockfd, mesg, size, 0, pserv_addr, servlen) != size)
                error.system("sendto error");
        // get acknowledgment
        n = recvfrom(sockfd, mesg, MAX_BUFFER, 0,
                (struct sockaddr *) 0, (int *) 0);
        if (n < 0)
            error.system("recvfrom error");
        mes2.end();
    }
    mes.writeout_logfile(true, true);
    mes.writeout_plain_logfile();
    mes2.writeout_histogram();
    mes2.writeout_plain_histogram();
}
// Main /////////////////////////////////////////////////////////////// Main //
/*
 * Example of client using the UDP protocol.
 *
 * paramteters:
 *
 *   argv[1]: server internet address (in dot-form)
 *   argv[2]: port number of server
 */
int
main(int argc, char *argv[])
{
    error.set_program_name(argv[0]);    
    if(argc!=3)
    {
        cerr << "Usage: " << argv[0] << " serveraddr port" << endl;
        exit(EXIT_FAILURE);
    }
    int sockfd;
    struct sockaddr_in  cli_addr, serv_addr;
    int portnumber = -1;
    // get port number
    portnumber = atoi(argv[2]);
    if(portnumber <1)
    {
        cerr << "illegal port number" << endl;
        exit(EXIT_FAILURE);
    }
    // Fill in the structure "serv_addr" with the address of the
    // server that we want to send to.
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family      = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]); // server addr
    serv_addr.sin_port        = htons(portnumber);
    // create a UDP socket (an Internet datagram socket)
    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        error.system("client: can't create datagram socket");
    // bind any local address for us
    bzero((char *) &cli_addr, sizeof(cli_addr));    /* zero out */
    cli_addr.sin_family      = AF_INET;
    cli_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    cli_addr.sin_port        = htons(0);
    if (bind(sockfd, (struct sockaddr *) &cli_addr, sizeof(cli_addr)) < 0)
        error.system("client: can't bind local address");
    // do something...
    do_it(argv[0], sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    close(sockfd);
    return(EXIT_SUCCESS);
}