distSOCKET/udpclient.c

///////////////////////////////////////////////////////////////////////////////
// Filename: udpclient.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: show how to use UDP (this file: UDP client) (socket version)
//          needs udpserver(.c) as UDP server
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/02/20 08:57:43 muellerg: created
// 96/02/21 05:39:23 muellerg: documentation cleanup
// 96/03/19 04:41:19 muellerg: updated, functionality added
//
// possible improvements:
//
// more error checking
// should accept also ascii names for computer names
// port number check
// use time-out if no reply from server
///////////////////////////////////////////////////////////////////////////////


// 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"



// 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 get result
 *
 * in: data:       data to send (up to MAXLINE bytes)
 *     sockfd:     fd to use
 *     pserv_addr: ptr to appropriate sockaddr_XX structure
 *     servlen:    actual sizeof(*pserv_addr)
 */

void do_it(char *data, int sockfd, struct sockaddr *pserv_addr, int servlen)
{
    int n;
    char buffer[MAXLINE];

    if (sendto(sockfd, data, strlen(data)+1, 0, pserv_addr, servlen) != 
                                                    (int)(strlen(data)+1) )
        error.system("sendto error");

    // get result

    n = recvfrom(sockfd, buffer, MAXLINE, 0, (struct sockaddr *) 0, (int *) 0);
    if (n < 0)
        error.system("recvfrom error");

    if(strcmp(data,buffer) != 0)
    {
        cout << "UDP client: returned result is not equal to sent string!"
             << endl;
    }       
    else        
        cout << "UDP client: returned string is equal to sent string" << endl;
}




// Main /////////////////////////////////////////////////////////////// Main //

/*
 * Example of client using the UDP protocol.
 *
 * paramteters:
 *
 *   argv[1]: server internet address (in dot-form)
 *   argv[2]: port number of server
 *   argv[3]: string to send to server
 */


int
main(int argc, char *argv[])
{
    error.set_program_name(argv[0]);    

    if(argc!=4)
    {
        cerr << "Usage: " << argv[0] << " serveraddr port string" << 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);
    }


    // check length of data argument
    if( strlen(argv[3]) > (MAXLINE-1) )
    {
        error.warning("argument 3: string too long");
        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_it(argv[3], sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
 

    close(sockfd);

    return(EXIT_SUCCESS);
}