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);
}