Previous | Contents | Index |
Table A-1 lists the sample programs printed in this appendix. See Table 1-1 and Table 1-2 for a complete list of all the sample programs provided online in TCPIP$EXAMPLES.
File | See... |
---|---|
TCPIP$TCP_SERVER_QIO.C | Section A.1 |
TCPIP$UDP_SERVER_IPC.C | Section A.2 |
TCPIP$TCP_SERVER_IPC.C | Section A.3 |
TCPIP$TCP_SERVER_IPC_AUXS.C | Section A.4 |
TCPIP$TCP_CLIENT_IPC.C | Section A.5 |
A.1 TCP/IP Server Using QIO Calls
Example A-1 shows a TCP/IP server using QIO calls. You can access
this file online in TCPIP$EXAMPLES:TCPIP$TCP_SERVER_QIO.C.
Depending on your compiler, you can compile and link this program in any of the following ways:
$ CC /PREFIX=ALL TCPIP$TCP_SERVER_QIO.C $ LINK TCPIP$TCP_SERVER_QIO |
$ CXX /PREFIX=ALL/DEFINE=VMS TCPIP$TCP_SERVER_QIO.C $ LINK TCPIP$TCP_SERVER_QIO |
SYS$LIBRARY:TCPIP$IPC.OLB/LIB SYS$SHARE:VAXCRTL.EXE/SHARE |
$ CC /VAXC TCPIP$TCP_SERVER_QIO.C $ LINK TCPIP$TCP_SERVER_QIO, - SYS$LIBRARY:TCPIP$IPC/LIB, - SYS$INPUT/OPTIONS SYS$SHARE:TCPIP$IPC_SHR/SHARE SYS$SHARE:VAXCRTL.EXE/SHARE |
Example A-1 TCP/IP Server Using QIO Calls |
---|
#include <descrip.h> /* OpenVMS descriptor information */ #include <errno.h> /* UNIX style error codes for I/O routines */ #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 <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 <tcpip$inetdef.h> /* Network definitions */ /* Convert short port number from host to network byte order */ #define htons(x) ((unsigned short)((x<<8)|(x>>8))) main() { int status; /* For return status */ short channel; /* INET channel */ short channel_1; /* Template for ACCEPT */ short sck_parm[2]; /* Socket creation parameter */ short iosb[4]; /* I/O status block */ char buf[512]; int buflen = 512; /* Buffer length */ int retval; short port; unsigned char *dummy; unsigned int r_retlen; int one=1; struct SOCKADDRIN local_host, remote_host; struct IL2 { unsigned int il2_length; char *il2_address; } lhst_adrs; struct IL3 { unsigned int il3_length; char *il3_address; unsigned int* il3_retlen; } rhst_adrs; struct dsc$descriptor inet_dev = {10, DSC$K_CLASS_S, DSC$K_DTYPE_T, "TCPIP$DEVICE"}; struct { short len, param; int *ptr; } item_list[] = {{sizeof(one), TCPIP$C_REUSEADDR, (int*)0 }}, options = {sizeof(item_list), TCPIP$C_SOCKOPT, (int*)0 }; item_list[0].ptr = &one; options.ptr = (int*)item_list; lhst_adrs.il2_length = sizeof local_host; lhst_adrs.il2_address = (char *)&local_host; rhst_adrs.il3_length = sizeof remote_host; rhst_adrs.il3_address = (char*)&remote_host; rhst_adrs.il3_retlen = &r_retlen; sck_parm[0] = TCPIP$C_TCP; /* TCP/IP protocol */ sck_parm[1] = INET_PROTYP$C_STREAM; /* Stream type of socket */ local_host.SIN$W_FAMILY = TCPIP$C_AF_INET; /* INET family */ local_host.SIN$L_ADDR = TCPIP$C_INADDR_ANY; /* Any address */ while (retval != 1) { printf("Enter local port number:\n"); retval = scanf("%hd", &port); if (retval == 1) local_host.SIN$W_PORT = htons(port); else scanf("%s",buf); /* discard bad input */ } /* Assign two channels to the device. */ status = sys$assign(&inet_dev, &channel, 0, 0); if (status & 1) status = sys$assign(&inet_dev, &channel_1, 0, 0); if (!(status & 1)) { printf("Failed to assign channel to device.\n"); exit(status); } /* Create the socket and set the REUSEADDR option. */ status = sys$qiow(3, /* Event flag */ channel, /* Channel number */ IO$_SETMODE, /* I/O function */ iosb, /* I/O status block */ 0, 0, &sck_parm, 0, /* P1 socket creation parameter */ 0, 0, &options, 0); /* P5 socket option descriptor */ if (status & 1) status = iosb[0]; if (!(status & 1)) { printf("Failed to create the device socket.\n"); exit(status); } /* Bind to chosen port number (after REUSEADDR is set above). */ status = sys$qiow(3, /* Event flag */ channel, /* Channel number */ IO$_SETMODE, /* I/O function */ iosb, /* I/O status block */ 0, 0, 0, 0, &lhst_adrs, /* P3 local socket name */ 3, /* P4 connection backlog */ 0, 0); if (status & 1) status = iosb[0]; if (!(status & 1)) { printf("Failed to bind the device socket.\n"); exit(status); } /* Accept a connection from a client. */ status = sys$qiow(3, /* Event flag */ channel, /* Channel number */ IO$_ACCESS|IO$M_ACCEPT, /* I/O function */ iosb, /* I/O status block */ 0, 0, 0, 0, &rhst_adrs, /* P3 Remote IP address*/ &channel_1, /* P4 Channel for new socket */ 0, 0); if (status & 1) status = iosb[0]; if (!(status & 1)) { printf("Failed to accept a connection from a client.\n"); exit(status); } dummy = (unsigned char *)&remote_host.SIN$L_ADDR; printf("Connection from host: %d.%d.%d.%d, port: %d\n", dummy[0], dummy[1], dummy[2], dummy[3], htons(remote_host.SIN$W_PORT)); /* Read I/O buffer. */ status = sys$qiow(3, /* Event flag */ channel_1, /* Channel number */ IO$_READVBLK, /* I/O function */ iosb, /* I/O status block */ 0, 0, buf, /* P1 buffer */ buflen, /* P2 buffer length */ 0, 0, 0, 0); if (status & 1) status = iosb[0]; if (!(status & 1)) printf("Failed to read from socket.\n"); /* If all is well, print message */ printf ("Received text: %s\n", buf); /* Shut down the socket (optional). */ status = sys$qiow(3, channel_1, IO$_DEACCESS|IO$M_SHUTDOWN, iosb, 0, 0, 0, 0, 0, TCPIP$C_DSC_ALL, /* P4 Discard all packets */ 0, 0); if (status & 1) status = iosb[0]; if (!(status & 1)) printf("Failed to shut down the socket.\n"); /* Close the sockets -- accepted and listener (optional). */ status = sys$qiow(3, channel_1, IO$_DEACCESS, iosb, 0, 0, 0, 0, 0, 0, 0, 0); if (status & 1) status = sys$qiow(3, channel, IO$_DEACCESS, iosb, 0, 0, 0, 0, 0, 0, 0, 0); if (status & 1) status = iosb[0]; if (!(status & 1)) printf("Failed to close the socket.\n"); /* Deassign the device channels. */ status = sys$dassgn(channel_1); if (status & 1) status = sys$dassgn(channel); if (!(status & 1)) printf("Failed to deassign the channel.\n"); } |
A.2 UDP/IP Server --- C Socket Example
Example A-2 shows a UDP/IP server using the IPC socket interface. You
can access this file online in TCPIP$EXAMPLES:TCPIP$UDP_SERVER_IPC.C.
This example shows you how to create a SOCK_DGRAM (UDP) socket type, bind it, and select it to receive a message on the socket. 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.
The C Socket calls used in this program are:
Depending on your compiler, you can compile and link this program in any of the following ways:
$ CC /PREFIX=ALL TCPIP$UDP_SERVER_IPC.C $ LINK TCPIP$UDP_SERVER_IPC |
$ CXX /PREFIX=ALL/DEFINE=VMS TCPIP$UDP_SERVER_IPC.C $ LINK TCPIP$UDP_SERVER_IPC |
SYS$LIBRARY:TCPIP$IPC.OLB/LIB SYS$SHARE:VAXCRTL.EXE/SHARE |
$ CC /VAXC TCPIP$UDP_SERVER_IPC.C $ LINK TCPIP$UDP_SERVER_IPC, - SYS$LIBRARY:TCPIP$IPC/LIB, - SYS$INPUT/OPTIONS SYS$SHARE:TCPIP$IPC_SHR/SHARE SYS$SHARE:VAXCRTL.EXE/SHARE |
Example A-2 UDP/IP Server Using the C Socket Interface |
---|
#ifdef VMS #include <descrip.h> /* OpenVMS descriptor information */ #include <errno.h> /* UNIX style error codes for I/O routines */ #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 <tcpip$inetdef.h> /* 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> #include <time.h> /* timeval declared here */ #endif /*-----------------------------------------------------------*/ cleanup( int socket ) { int retval; /* * Shut down socket completely. */ retval = shutdown(socket,2); if (retval == -1) perror ("shutdown"); /* * Close socket. */ retval = close (socket); if (retval) perror ("close"); exit( 1 ); } /* end cleanup */ /*--------------------------------------------------------------------*/ main( int argc, char **argv ) { int rmask, wmask, emask; int sock_2; /* Socket 2 descriptor */ int buflen,fromlen; char recvbuf[BUFSIZ]; static struct sockaddr_in sock1_name; /* Address struct for socket1 */ static struct sockaddr_in sock2_name; /* Address struct for socket2 */ int namelength; struct hostent hostentstruct; /* Storage for hostent data */ struct hostent *hostentptr; /* Pointer to hostent data */ static char hostname[256]; /* Name of local host */ int retval; int flag; struct timeval timeout; /* * Check input parameters */ if (argc != 2 ) { printf("Usage: server portnumber.\n"); exit( 1 ); } /* * Open socket 2: AF_INET, SOCK_DGRAM. */ if ((sock_2 = socket (AF_INET, SOCK_DGRAM, 0)) == -1) { perror( "socket"); exit( 1 ); } /* * Get the local host name. */ retval = gethostname(hostname,sizeof hostname); if (retval) { perror ("gethostname"); cleanup(sock_2); } /* * Get pointer to network data structure for local host. */ if ((hostentptr = gethostbyname (hostname)) == NULL) { perror( "gethostbyname"); cleanup(sock_2); } /* * Copy hostent data to safe storage. */ hostentstruct = *hostentptr; /* * Fill in the 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(sock_2); } /* * Select socket to receive message. */ emask = wmask = 0; rmask = (1<<sock_2); /* set read mask */ timeout.tv_sec = 30; timeout.tv_usec = 0; retval = select( 32, &rmask, &wmask, &emask, &timeout ); switch (retval) { case -1: { perror("select"); cleanup(sock_2); } case 0: { printf("Select timed out with status 0.\n"); cleanup(sock_2); } default: if ((rmask & (1<<sock_2)) == 0) { printf("Select not reading on sock_2.\n"); cleanup(sock_2); } } /*switch*/ /* * Recvfrom buffer - from sock1 on sock2. */ buflen = sizeof(recvbuf); fromlen = sizeof(sock1_name); flag = 0; /* flag may be MSG_OOB and/or MSG_PEEK */ retval = recvfrom( sock_2, recvbuf, buflen, flag, (struct sockaddr*)&sock1_name, &fromlen); if (retval == -1) perror("recvfrom"); else printf (" %s\n", recvbuf); /* * Call cleanup to shut down and close socket. */ cleanup(sock_2); } /* end main */ |
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 TCPIP$EXAMPLES:TCPIP$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 TCPIP$TCP_SERVER_IPC.C $ LINK TCPIP$TCP_SERVER_IPC |
$ CXX /PREFIX=ALL/DEFINE=VMS TCPIP$TCP_SERVER_IPC.C $ LINK TCPIP$TCP_SERVER_IPC |
SYS$LIBRARY:TCPIP$IPC.OLB/LIB SYS$SHARE:VAXCRTL.EXE/SHARE |
$ CC /VAXC TCPIP$TCP_SERVER_IPC.C $ LINK TCPIP$TCP_SERVER_IPC, - SYS$LIBRARY:TCPIP$IPC/LIB, - SYS$INPUT/OPTIONS SYS$SHARE:TCPIP$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 <tcpip$inetdef.h> /* 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 */ |
Previous | Next | Contents | Index |