distTLI/tcpclient.c
///////////////////////////////////////////////////////////////////////////////
// Filename: tcpclient.c
///////////////////////////////////////////////////////////////////////////////
// Purpose: show how to use TCP (this file: TCP client) (TLI version)
//          uses tcpserver(.c) as TCP server
///////////////////////////////////////////////////////////////////////////////
// History:
// ========
//
// Date     Time     Name      Description   
// -------- -------- --------  ------------------------------------------------
// 96/02/26 13:52:19 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.
 */
void doit(FILE *fp, int tfd)
{
    int n, flags;
    char    sendline[MAXLINE], recvline[MAXLINE + 1];
    while (fgets(sendline, MAXLINE, fp) != NULL) {
        n = strlen(sendline);
        if (t_snd(tfd, sendline, n, 0) != n)
            error.system("client: t_snd error");
        
        // Now read a line from the transport endpoint and write it to
        // our standard output.
        n = t_rcv(tfd, recvline, MAXLINE, &flags);
        if (n < 0)
            error.system("client: t_rcv error");
        recvline[n] = 0;    /* null terminate */
        fputs(recvline, stdout);
    }
    if (ferror(fp))
        error.system("client: error reading file");
}
// Main /////////////////////////////////////////////////////////////// Main //
/*
 * Example of client using TCP 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_call *callptr;
    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);
    }
    // Create a TCP transport endpoint and bind it.
    if ( (tfd = t_open(DEV_TCP, O_RDWR, 0)) < 0)
    {
        error.warning("client: can't t_open %s", DEV_TCP);
        exit(EXIT_FAILURE);
    }   
    if (t_bind(tfd, (struct t_bind *) 0, (struct t_bind *) 0) < 0)
        error.system("client: t_bind error");
    
    // Fill in the structure "serv_addr" with the address of the
    // server that we want to connect with.
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family      = AF_INET;
    serv_addr.sin_addr.s_addr = inet_addr(argv[1]);
    serv_addr.sin_port        = htons(portnumber);
    // Allocate a t_call structure, and initialize it.
    // Let t_alloc() initialize the addr structure of the t_call structure.
    if ( (callptr = (struct t_call *) t_alloc(tfd, T_CALL, T_ADDR)) == NULL)
        error.system("client: t_alloc error");
    callptr->addr.maxlen = sizeof(serv_addr);
    callptr->addr.len    = sizeof(serv_addr);
    callptr->addr.buf    = (char *) &serv_addr;
    callptr->opt.len     = 0;       // no options 
    callptr->udata.len   = 0;       // no user data with connect 
    // Connect to the server.
    if (t_connect(tfd, callptr, (struct t_call *) 0) < 0)
        error.system("client: can't t_connect to server");
    doit(stdin, tfd);   // do it all 
    close(tfd);
    exit(EXIT_SUCCESS);
}