/* ******************************************************************************* ** FILE: UDPdriver_client.C -- example program demonstrating usage of ** network programming library using UDPDRIVER $QIO's ** ** PRODUCT: TCPware for VMS ** ** VERSION: V5.6 ** ** Copyright (c) 2001, 2002 by ** Process Software LLC ** Framingham, Massachusetts ** ** Copyright (c) 1997-1999 by ** Process Software Corporation ** Framingham, Massachusetts ** ** This software is furnished under a license for use on a ** single computer system and may be copied only with the ** inclusion of the above copyright notice. This software, or ** any other copies thereof, may not be provided or otherwise ** made available to any other person except for use on such ** system and to one who agrees to these license terms. Title ** to and ownership of the software shall at all times remain ** in Process Software LLC's name. ** ** The information in this document is subject to change ** without notice and should not be construed as a commitment ** by Process Software LLC. Process Software LLC assumes no ** responsibility for any errors that may appear in this document. ** ** ** ABSTRACT: ** ** UDPdriver_server.c and UDPdriver_client.c are a pair of example programs ** illustrating the use of datagrams via VMS's SYS$QIO system service ** calls to the UDPdriver. ** ** ** ** CLIENT SEQUENCE OF OPERATIONS: ** 1. Assign an I/O channel to UDP0: $ASSIGN; ** 2. Optionally open receive port: $QIO(IO$_SETMODE|IO$M_CTRL|IO$M_STARTUP); ** (this is not done below since no read is done) ** 3. Exchange data: $QIO(IO$_WRITEVBLK), $QIO(IO$_READVBLK); ** 4. Deassign the channel: $DASSGN; ** ** ** BUILDING EXECUTABLES: ** ** 1. on VAX : ** with VAXC: ** $ CC UDPDRIVER_CLIENT.C ** $ LINK UDPDRIVER_CLIENT, TCPWARE:UCX$IPC/LIB, SYS$INPUT/OPTIONS ** SYS$SHARE:VAXCRTL/SHARE ** ** Alternatively TCPware's socket library can be used: ** $ LINK UDPDRIVER_CLIENT, SYS$INPUT/OPTIONS ** SYS$SHARE:TCPWARE_SOCKLIB_SHR/SHARE ** SYS$SHARE:VAXCRTL/SHARE ** ** with DECC: ** $ CC/DECC/PREFIX_LIBRARY_ENTRIES=ALL UDPDRIVER_CLIENT.C ** $ LINK UDPDRIVER_CLIENT ** ** 2. on ALPHA: ** $ CC/PREFIX_LIBRARY_ENTRIES=ALL UDPDRIVER_CLIENT.C ** $ LINK UDPDRIVER_CLIENT ** ******************************************************************************* ** REQUEST: If you have comments, please send them to "support@process.com" ******************************************************************************* */ #include /* Standard C i/o */ #include #include /* VAX/VMS System services */ #include /* for STS$M_SUCCESS */ #include /* Descriptors */ #include /* VAX/VMS i/o definitions */ #include #include /* ** Macros to check VMS success/failure status */ #define SUCCESS(status) (status & STS$M_SUCCESS) #define FAILURE(status) (!(status & STS$M_SUCCESS)) /* ** Service information */ #define SERVER_PORT 65000 #define SERVICE "test_discard" #define PROTO "udp" /* ** Values for boolean variables */ #define FALSE 0 #define TRUE 1 #if defined(__DECC) || defined(__DECCXX) #pragma __member_alignment __save #pragma __nomember_alignment #endif /* ** I/O status block */ struct IOSB_struct { short unsigned status; short unsigned byte_count; long dev_data; }; /* ** address buffer structure */ struct addr_struct { unsigned long src_addr; unsigned short src_port; /* ignored w/ WRITEVBLK */ short null_1; unsigned long dest_addr; unsigned short dest_port; short null_2; }; #if defined(__DECC) || defined(__DECCXX) #pragma __member_alignment __restore #endif /* ** function prototypes */ char *gets( char *); void exit( int); long sys$assign( struct dsc$descriptor_s *, unsigned short *, unsigned long, struct dsc$descriptor_s *); long sys$qiow( ); /* no prototyping due to varying P1 - P6 */ long sys$dassgn( unsigned short); main() { unsigned short channel; /* UDP channel number */ unsigned short port; /* UDP port number */ int status; /* For return status */ int continue_IO; /* boolean continue flag */ int got_host; char server_name[80]; int buflen; char buffer[1024]; struct hostent *hostent_P; struct servent *servent_P; struct IOSB_struct iosb; struct addr_struct write_addr; /* String descriptor for the TCP0 device */ static $DESCRIPTOR( UDP0_dev, "UDP0"); /* Assign a channel to UDP0 to clone a new device */ status = sys$assign( &UDP0_dev, &channel, 0, 0); if (FAILURE( status) ) { printf("Failed to assign channel to device UDP0.\n"); exit( status); } /* ** Get server port number for named serice. ** If unknown, use default define. */ if ( (servent_P = getservbyname( SERVICE, PROTO)) != NULL) port = servent_P->s_port; else port = SERVER_PORT; printf("Will connect to server port #: %d\n", port); /* Query user for server name and get corresponding internet address. */ for (got_host = FALSE; got_host == FALSE; ) { printf("Enter name of remote host (e.g. localhost) : "); gets( server_name); if ((hostent_P = gethostbyname(server_name)) == NULL) { printf("Error, gethostbyname failed\n"); } else { got_host = TRUE; /* setup write_addr struct for $QIO WRITEVBLK P3 argument */ write_addr.src_addr = 0; /* UPDdriver will supply */ write_addr.null_1 = 0; memcpy( (char *)&write_addr.dest_addr, hostent_P->h_addr, hostent_P->h_length); write_addr.dest_port = port; write_addr.null_2 = 0; } } /* ** Keep getting input string & send to the server, till "CLOSE" is input. */ printf("\n\nKeep getting keyboard input & sending to the server,\n till ^Z (client exit) or 'CLOSE' (server exit) is input.\n\n"); for (continue_IO = TRUE; continue_IO; ) { /* ** Prepare message to send: ** Setup message (Replace with your application function.) */ printf("\nInput string to send. sends default: \n"); if ( gets( buffer) == NULL) break; buflen = strlen(buffer); /* if no input, setup default message */ if ( 0 == buflen) { strcpy( buffer, "User Datagram Protocol is described in RFC 768"); buflen = strlen(buffer); } /* ** Send the message */ status = sys$qiow( 0, channel, IO$_WRITEVBLK, &iosb, 0, 0, buffer, /* P1: buffer */ buflen, /* P2: buffer size */ &write_addr, /* P3: adr of src/dest info buf */ 0,0,0); if ( SUCCESS( status) ) status = iosb.status; if ( FAILURE( status) ) { printf("Error sending message. Status = %x\n", status ); break; } if ( 0 == strcmp( buffer, "CLOSE") || 0 == strcmp( buffer, "close") ) continue_IO = FALSE; } /* Deassign the channel */ status = sys$dassgn(channel); }