A.3 TCP/IP Server --- C Socket Example
Example A-3 shows a TCP/IP server using the C Socket interface. You 
can access this file online in UCX$EXAMPLES:UCX$TCP_SERVER_IPC.C.
This example creates a SOCK_STREAM (TCP) socket type, binds and listens on the socket, receives a message and closes the connection. Error messages are printed to the screen.
This example is portable to UNIX. The include files are conditionally defined for both OpenVMS VAX and Alpha systems, and "perror" is used for error reporting.
This example uses the following C Socket routines:
Depending on your compiler, you can compile and link this program in any of the following ways:
$ CC /PREFIX=ALL UCX$TCP_SERVER_IPC.C $ LINK UCX$TCP_SERVER_IPC
$ CXX /PREFIX=ALL/DEFINE=VMS UCX$TCP_SERVER_IPC.C $ LINK UCX$TCP_SERVER_IPC
SYS$LIBRARY:UCX$IPC.OLB/LIB SYS$SHARE:VAXCRTL.EXE/SHARE
$ CC /VAXC UCX$TCP_SERVER_IPC.C 
$ LINK UCX$TCP_SERVER_IPC, - 
        SYS$LIBRARY:UCX$IPC/LIB, - 
        SYS$INPUT/OPTIONS 
SYS$SHARE:UCX$IPC_SHR/SHARE 
SYS$SHARE:VAXCRTL.EXE/SHARE 
Example A-3 TCP/IP Server Using the C Socket Interface
#ifdef VMS 
#include <descrip.h>        /* OpenVMS descriptor information */ 
#include <in.h>             /* Internet system constants and structures */ 
#include <inet.h>           /* Network address information */ 
#include <iodef.h>          /* I/O function code definitions */ 
#include <lib$routines.h>   /* LIB$ RTL-routine signatures */ 
#include <netdb.h>          /* Network database library information */ 
#include <signal.h>         /* UNIX style signal value definitions */ 
#include <socket.h>         /* TCP/IP socket definitions */ 
#include <ssdef.h>          /* SS$_<xyz> system service return status codes */ 
#include <starlet.h>        /* System service calls */ 
#include <stdio.h>          /* UNIX 'standard I/O' definitions   */ 
#include <stdlib.h>         /* General utilities */ 
#include <string.h>         /* String handling function definitions */ 
#include <ucx$inetdef.h>    /* UCX network definitions */ 
#include <unixio.h>         /* Prototypes for UNIX emulation functions */ 
 
#else 
#include <errno.h> 
#include <sys/types.h> 
#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <sys/uio.h> 
 
#endif 
 
/*-----------------------------------------------------------*/ 
 
cleanup( int how_many, int sock1, int sock2 ) 
{ 
        int retval; 
 
        /* 
         * Shut down and close sock1 completely. 
         */ 
        retval = shutdown(sock1,2); 
        if (retval == -1) 
                perror ("shutdown"); 
 
        retval = close (sock1); 
        if (retval) 
                perror ("close"); 
 
 
        /* 
         * If given, shutdown and close sock2. 
         */ 
        if (how_many == 2) 
        { 
                retval = shutdown(sock2,2); 
                if (retval == -1) 
                        perror ("shutdown"); 
 
                retval = close (sock2); 
                if (retval) 
                        perror ("close"); 
        } 
 
        exit( 1 ); 
 
} /* end cleanup*/ 
 
 
/*--------------------------------------------------------------------*/ 
main( int argc, char **argv ) 
{ 
 
        int     sock_2, sock_3;                /* sockets */ 
        static  char    message[BUFSIZ]; 
static  struct  sockaddr_in     sock2_name;    /* Address struct for socket2 */ 
static  struct  sockaddr_in     retsock2_name; /* Address struct for socket2 */ 
        struct  hostent         hostentstruct; /* Storage for hostent data   */ 
        struct  hostent         *hostentptr;   /* Pointer to hostent data    */ 
        static  char            hostname[256]; /* Name of local host         */ 
        int     flag; 
        int     retval;                        /* Helpful for debugging */ 
        int     namelength;   
 
 
        /* 
         * Check input parameters. 
         */ 
        if (argc != 2 ) 
                { 
                printf("Usage: server portnumber.\n"); 
                exit( 1 ); 
                } 
 
        /* 
         * Open socket 2: AF_INET, SOCK_STREAM. 
         */ 
        if ((sock_2 = socket (AF_INET, SOCK_STREAM, 0)) == -1) 
                { 
                perror( "socket"); 
                exit( 1 ); 
                } 
 
        /* 
         * Get the host local name. 
         */ 
        retval = gethostname(hostname,sizeof hostname); 
        if (retval) 
                { 
                perror ("gethostname"); 
                cleanup (1, sock_2, 0); 
                } 
 
        /* 
         * Get pointer to network data structure for socket 2. 
         */ 
        if ((hostentptr = gethostbyname (hostname)) == NULL) 
                { 
                perror( "gethostbyname"); 
                cleanup(1, sock_2, 0); 
                } 
 
        /* 
         * Copy hostent data to safe storage. 
         */ 
        hostentstruct = *hostentptr; 
 
        /* 
         * Fill in the name & address structure for socket 2. 
         */ 
        sock2_name.sin_family = hostentstruct.h_addrtype; 
        sock2_name.sin_port = htons(atoi(argv[1])); 
        sock2_name.sin_addr = * ((struct in_addr *) hostentstruct.h_addr); 
 
        /* 
         * Bind name to socket 2. 
         */ 
        retval = bind ( sock_2, 
                        (struct sockaddr*)&sock2_name, 
                        sizeof sock2_name ); 
        if (retval) 
                { 
                perror("bind"); 
                cleanup(1, sock_2, 0); 
                } 
 
        /* 
         * Listen on socket 2 for connections. 
         */ 
        retval = listen (sock_2, 5); 
        if (retval) 
                { 
                perror("listen"); 
                cleanup(1, sock_2, 0); 
                } 
 
        /* 
         * Accept connection from socket 2:      
         * accepted connection will be on socket 3. 
         */ 
        namelength = sizeof (sock2_name); 
        sock_3 = accept (sock_2, (struct sockaddr*)&sock2_name, &namelength); 
        if (sock_3 == -1) 
                { 
                perror ("accept"); 
                cleanup( 2, sock_2, sock_3); 
                } 
 
        /* 
         * Receive message from socket 1. 
         */ 
        flag = 0; /* maybe 0 or MSG_OOB or MSG_PEEK */ 
 
        retval = recv(sock_3, message ,sizeof (message), flag); 
        if (retval == -1) 
                { 
                perror ("receive"); 
                cleanup( 2, sock_2, sock_3); 
                } 
           else 
              printf (" %s\n", message); 
 
        /* 
         * Call cleanup to shut down and close sockets. 
         */ 
        cleanup(2, sock_2, sock_3); 
 
 } /* end main */ 
 
A.4 TCP/IP Server Accepting a Connection from the Auxiliary  Server 
Example A-4 shows a TCP/IP server accepting a connection from the 
auxiliary server. You can access this file online in 
UCX$EXAMPLES:UCX$TCP_SERVER_IPC_AUXS.C.
In this example, the TCP/IP server accepts a connection from the auxiliary server, sends the string "Hello, world!" and immediately closes the connection and terminates. For this example to work correctly, you need to create a one-line command procedure and issue the SET SERVICE command after you compile and link the program, as follows:
$ CC /PREFIX=ALL UCX$TCP_SERVER_IPC_AUXS.C $ LINK UCX$TCP_SERVER_IPC_AUXS
$ CXX /PREFIX=ALL/DEFINE=VMS UCX$TCP_SERVER_IPC_AUXS.C $ LINK UCX$TCP_SERVER_IPC_AUXS
SYS$LIBRARY:UCX$IPC.OLB/LIB SYS$SHARE:VAXCRTL.EXE/SHARE
$ CC /VAXC UCX$TCP_SERVER_IPC_AUXS.C 
$ LINK UCX$TCP_SERVER_IPC_AUXS, - 
        SYS$LIBRARY:UCX$IPC/LIB, - 
        SYS$INPUT/OPTIONS 
SYS$SHARE:UCX$IPC_SHR/SHARE 
SYS$SHARE:VAXCRTL.EXE/SHARE 
  $ RUN ddcu:[dir]UCX$TCP_SERVER_IPC_AUXS
UCX> SET SERVICE HELLO /PORT=1234 /USER=username /PROCESS=HI_WORLD - _UCX> /FILE=ddcu:[dir]HELLO_STARTUP.COM UCX>ENABLE SERVICE HELLO
Example A-4 TCP/IP Server Accepting a Connection from the Auxiliary Server
#include <socket.h> 
#include <unixio.h> 
#include <string.h> 
#include <ucx$inetdef.h> 
 
main() { 
        int s; 
        char *message = "Hello, world!\r\n"; 
 
        s = socket(UCX$C_AUXS, 0, 0); 
        write(s, message, strlen(message)); 
        close(s); 
} 
 
A.5 TCP/IP Client Using the IPC Socket Interface  
Example A-5 shows a TCP/IP client using the C Socket interface. You 
can access this file online in UCX$EXAMPLES:UCX$TCP_CLIENT_IPC.C.
This example creates a socket of type SOCK_STREAM (TCP), initiates a connection to the remote host, sends a message to the remote host, and closes the connection. Error messages are printed to the screen.
This example is portable to UNIX. The include files are conditionally defined for both systems, and "perror" is used for error reporting.
Depending on your compiler, you can compile and link this program in any of the following ways:
$ CC /PREFIX=ALL UCX$TCP_CLIENT_IPC.C $ LINK UCX$TCP_CLIENT_IPC
$ CXX /PREFIX=ALL/DEFINE=VMS UCX$TCP_CLIENT_IPC.C $ LINK UCX$TCP_CLIENT_IPC
SYS$LIBRARY:UCX$IPC.OLB/LIB SYS$SHARE:VAXCRTL.EXE/SHARE
$ CC /VAXC UCX$TCP_CLIENT_IPC.C 
$ LINK UCX$TCP_CLIENT_IPC, - 
        SYS$LIBRARY:UCX$IPC/LIB, - 
        SYS$INPUT/OPTIONS 
SYS$SHARE:UCX$IPC_SHR/SHARE 
SYS$SHARE:VAXCRTL.EXE/SHARE 
Example A-5 TCP/IP Client Using the IPC Socket Interface
#if defined(VMS) || defined(__VMS) 
#include  <stdlib.h> 
#include  <unixio.h> 
#include  <errno.h> 
#include  <types.h> 
#include  <stdio.h> 
#include  <socket.h> 
#include  <in.h> 
#include  <netdb.h>             /* Change hostent to comply with BSD 4.3*/ 
#include  <inet.h> 
#include  <ucx$inetdef.h>       /* INET symbol definitions */ 
#else 
#include <errno.h> 
#include <sys/types.h> 
#include <stdio.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
#include <arpa/inet.h> 
#include <sys/uio.h> 
#endif 
 
/* 
*   MACRO DEFINITIONS 
*/ 
 
#ifndef vms 
#define TRUE 1 
#define FALSE 0 
#endif 
 
void cleanup(int shut, int socket); 
 
/*--------------------------------------------------------------------*/ 
main(int argc, char     **argv) 
{ 
        int     sock_1;                        /* Socket */ 
static  char   message[] = "Hi there."; 
static  struct  sockaddr_in sock2_name;         /* Address struct for socket2*/ 
        struct  hostent         hostentstruct;  /* Storage for hostent data  */ 
        struct  hostent         *hostentptr;    /* Pointer to hostent data   */ 
        static  char            hostname[256];  /* Name of local host        */ 
        int     flag; 
        int     retval;                         /* Helpful for debugging */ 
        int     shut = FALSE;                   /* Flag to cleanup */ 
 
        /* 
         * Check input parameters. 
         */ 
        if (argc != 3 ) 
                { 
                printf("Usage: client hostname portnumber.\n"); 
                exit(EXIT_FAILURE); 
                } 
 
        /* 
         * Open socket 1: AF_INET, SOCK_STREAM. 
         */ 
        if ((sock_1 = socket (AF_INET, SOCK_STREAM, 0)) == -1) 
                { 
                perror( "socket"); 
                exit(EXIT_FAILURE); 
                } 
 
        /* 
         *Get pointer to network data structure for socket 2 (remote host). 
         */ 
        if ((hostentptr = gethostbyname (argv[1])) == NULL) 
                { 
                perror( "gethostbyname"); 
                cleanup(shut, sock_1); 
                } 
 
        /* 
         * Copy hostent data to safe storage. 
         */ 
        hostentstruct = *hostentptr; 
 
        /* 
         * Fill in the name & address structure for socket 2. 
         */ 
        sock2_name.sin_family = hostentstruct.h_addrtype; 
        sock2_name.sin_port = htons(atoi(argv[2])); 
        sock2_name.sin_addr = * ((struct in_addr *) hostentstruct.h_addr); 
 
        /* 
         * Connect socket 1 to sock2_name. 
         */ 
        retval = connect(sock_1, (struct sockaddr *)&sock2_name, 
                        sizeof (sock2_name)); 
        if (retval) 
                { 
                perror("connect"); 
                cleanup(shut, sock_1); 
                } 
 
        /* 
         * Send message to socket 2. 
         */ 
        flag = 0;       /* maybe 0 or MSG_OOB */ 
        retval = send(sock_1, message ,sizeof (message), flag); 
        if (retval < 0) 
                { 
                perror ("send"); 
                shut = TRUE; 
                } 
 
        /* 
         * Call cleanup to shut down and close socket. 
         */ 
        cleanup(shut, sock_1); 
 
 } /* end main */ 
 
/*-----------------------------------------------------------*/ 
 
void cleanup(int shut, int socket) 
 
{ 
        int    retval; 
 
        /* 
         * Shut down socket completely -- only if it was connected 
         */ 
         if (shut) { 
                retval = shutdown(socket,2); 
                if (retval == -1) 
                        perror ("shutdown"); 
         } 
 
 
        /* 
         * Close socket. 
         */ 
        retval = close (socket); 
        if (retval) 
                perror ("close"); 
 
        exit(EXIT_SUCCESS); 
 
 }