distTLI/udpclient.c

///////////////////////////////////////////////////////////////////////////////
// Filename: udpclient.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: show how to use UDP (this file: UDP client) (TLI version)
//          needs udpserver(.c) as UDP server
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/02/26 14:06:12 muellerg: created
//
///////////////////////////////////////////////////////////////////////////////


// Feature test switches ///////////////////////////// Feature test switches //
    /* NONE */


// System headers /////////////////////////////////////////// System headers //

#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>

#include <tiuser.h> 
#include <sys/types.h>
#include <sys/socket.h>
// #include <sys/in.h>              

#ifdef sun
// O_RDWR
#include <sys/fcntl.h>
#endif


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

/*
 * Read the contents of the FILE *fp, write each line to the transport
 * endpoint (to the server process), then read a line back from
 * the transport endpoint and print it on the standard output.
 *
 * in: tfd:       tli descriptor
 *     sudataptr: unitdata for sends
 *     fp:        FILE pointer
 */

void doit(int tfd, struct t_unitdata *sudataptr, FILE *fp)
{
    int n, flags;
    char sendline[MAXLINE], recvline[MAXLINE + 1];
    struct t_unitdata *rudataptr;   // unitdata for receives 

    /*
     * Allocate memory for the t_unitdata structure and the address field
     * in that structure.  This allows any size of address to be handled
     * by this function.
     */

    rudataptr = (struct t_unitdata *) t_alloc(tfd, T_UNITDATA, T_ADDR);
    if (rudataptr == NULL)
        error.system("server: t_alloc error for T_UNITDATA");

    while (fgets(sendline, MAXLINE, fp) != NULL)
    {
        n = strlen(sendline);
        sudataptr->udata.len = n;
        sudataptr->udata.buf = sendline;
        if (t_sndudata(tfd, sudataptr) < 0)
            error.system("client: t_sndudata error");


        // Now read a message from the transport endpoint and
        // write it to our standard output.

        rudataptr->opt.maxlen = 0;  // don't care about options 
        rudataptr->udata.maxlen = MAXLINE;
        rudataptr->udata.buf    = recvline;

        if (t_rcvudata(tfd, rudataptr, &flags) < 0)
            error.system("client: t_rcvudata error");

        recvline[rudataptr->udata.len] = 0; // null terminate 
        fputs(recvline, stdout);
    }

    if (ferror(fp))
        error.system("client: error reading file");
}


// 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 tfd;
    struct t_unitdata unitdata;
    struct sockaddr_in serv_addr;

    int portnumber = -1;


    // get port number

    portnumber = atoi(argv[2]);
    if(portnumber <1)
    {
        cerr << "illegal port number" << endl;
        exit(EXIT_FAILURE);
    }

    // Open a UDP endpoint.

    if ( (tfd = t_open(DEV_UDP, O_RDWR, (struct t_info *) 0)) < 0)
    {
        error.warning("client: can't t_open %s", DEV_UDP);
        exit(EXIT_FAILURE);
    }


    // Bind any local address for us.

    if (t_bind(tfd, (struct t_bind *) 0, (struct t_bind *) 0) < 0)
        error.system("client: t_bind error");


    // Initialize a sockaddr_in structure with the address of the
    // the server we want to send datagrams 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);

    // Now initialize a unitdata structure for sending to the server.

    unitdata.addr.maxlen = sizeof(serv_addr);   // server's addr 
    unitdata.addr.len    = sizeof(serv_addr);
    unitdata.addr.buf    = (char *) &serv_addr;
    unitdata.opt.maxlen  = 0;                   // no options 
    unitdata.opt.len     = 0;
    unitdata.opt.buf     = (char *) 0;

    doit(tfd, &unitdata, stdin);    // do it all 

    t_close(tfd);
    return(EXIT_SUCCESS);
}