![]() |
||||||||||
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() ![]() |
![]() HP OpenVMS systems documentation ![]() ![]() |
![]() |
Previous | Contents | Index |
E.2.3 TCP Server Accepting a Connection from the Auxiliary Server
Example E-6 shows how a typical TCP/IP IPv4 server uses $QIO system
services to handle network I/O operations and the server accepts
connections from the auxiliary server.
Example E-6 TCP Auxiliary Server (System Services) |
---|
#pragma module tcpip$tcp_server_qio_auxs \ "V5.1-00" /* * Copyright 2000 Compaq Computer Corporation * * COMPAQ Registered in U.S. Patent and Trademark Office. * * Confidential computer software. Valid license from Compaq * or authorized sublicensor required for possession, use or * copying. Consistent with FAR 12.211 and 12.212, Commercial * Computer Software, Computer Software Documentation, and * Technical Data for Commercial Items are licensed to the * U.S. Government under vendor's standard commercial license. * * ++ * FACILITY: * * EXAMPLES * * ABSTRACT: * * This is an example of a TCP/IP IPv4 server using OpenVMS * QIO system services to handle network I/O operations. In * addition, it shows how to accept connections from the * auxiliary server. * * Refer to 'Build, Configuration, and Run Instructions' for * details on how to build, configure, and run this program. * * ENVIRONMENT: * * OpenVMS Alpha/VAX V7.1 * TCP/IP Services V5.0 or higher * * AUTHOR: * * TCPIP Development Group, CREATION DATE: 23-May-1989 * * -- */ /* Build, Configuration, and Run Instructions */ /* * BUILD INSTRUCTIONS: * * To build this example program use commands of the form, * * using the DEC "C" compiler: * * $ cc/prefix=all TCPIP$TCP_SERVER_QIO_AUXS.C * $ link TCPIP$TCP_SERVER_QIO_AUXS * * using the DEC "C++" compiler: * * $ cxx/prefix=all/define=VMS TCPIP$TCP_SERVER_QIO_AUXS.C * $ link TCPIP$TCP_SERVER_QIO_AUXS * * * CONFIGURATION INSTRUCTIONS: * * To configure this example program: * * 1) Create a service run command procedure, named HELLO_RUN.COM, that * contains the following lines: * * $ define sys$output ddcu:[directory]hello_service.log * $ define sys$error ddcu:[directory]hello_service.log * $ run ddcu:[directory]tcpip$tcp_server_qio_auxs.exe * * where: ddcu:[directory] is the device and directory of where the * hello service run command procedure file resides * * 2) Create a service database entry for the hello service as shown below: * * $ tcpip set service hello - * _$ /port=12345 - * _$ /protocol=tcp - * _$ /user=vms_user_account - * _$ /process_name=hello_world - * _$ /file=ddcu:[directory]hello_run.com * * 3) Enable the hello service to run as shown below: * * $ tcpip enable service hello * * * RUN INSTRUCTIONS: * * To run this example program: * * 1) Start the client program, entering the server host as shown below: * * $ run tcpip$tcp_client_sock * Enter remote host: * * Note: You can specify a server host by using either an IPv4 * address in dotted-decimal notation (e.g. 16.20.10.56) * or a host domain name (e.g. serverhost.compaq.com). * * 2) The auxiliary server receives the hello service request, creates a * process, then executes the commands in hello_run.com to run this * server program. This server program then logs client connection * information and client data to the service log before replying to * the client host with a message of "Hello, world!". * */ /* * INCLUDE FILES: */ #include <descrip.h> /* define OpenVMS descriptors */ #include <efndef.h> /* define 'EFN$C_ENF' event flag */ #include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <inet.h> /* define network address info */ #include <iodef.h> /* define i/o function codes */ #include <ssdef.h> /* define system service status codes */ #include <starlet.h> /* define system service calls */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #include <stsdef.h> /* define condition value fields */ #include <tcpip$inetdef.h> /* define tcp/ip network constants, */ /* structures, and functions */ * STRUCTURE DEFINITIONS: */ struct iosb { /* i/o status block */ unsigned short status; /* i/o completion status */ unsigned short bytcnt; /* bytes transferred if read/write */ void *details; /* address of buffer or parameter */ }; struct itemlst_2 { /* item-list 2 descriptor/element */ unsigned short length; /* length */ unsigned short type; /* parameter type */ void *address; /* address of item list */ }; struct itemlst_3 { /* item-list 3 descriptor/element */ unsigned short length; /* length */ unsigned short type; /* parameter type */ void *address; /* address of item list */ unsigned int *retlen; /* address of returned length */ }; struct sockchar { /* socket characteristics buffer */ unsigned short prot; /* protocol */ unsigned char type; /* type */ unsigned char af; /* address format */ }; /* * FORWARD REFERENCES: */ int main( void ); /* server main */ /* Server Main */ /* * FUNCTIONAL DESCRIPTION: * * This is the server's main-line code. It handles all the tasks of the * server including: socket creation, writing client connection data, * and terminating client connections. * * This example program implements a typical TCP IPv4 server using QIO * system services to handle network i/o operations. In addition, it * uses the auxiliary server to accept client connections. * * 1) To create a socket: * * sys$assign() and sys$qiow(IO$_SETMODE) * * 2) To transfer data: * * sys$qiow(IO$_WRITEVBLK) * * 3) To close and delete a socket: * * sys$qiow(IO$_DEACCESS) and sys$dassgn() * * This function is invoked by the DCL "RUN" command (see below); the * function's completion status is interpreted by DCL and if needed, * an error message is displayed. * * SYNOPSIS: * * int main( void ) * * FORMAL PARAMETERS: * * ** None ** * * IMPLICIT INPUTS: * * ** None ** * * IMPLICIT OUTPUTS: * * ** None ** * * FUNCTION VALUE: * * completion status * * SIDE EFFECTS: * * ** None ** * */ int main( void ) { struct iosb iosb; /* i/o status block */ unsigned int status; /* system service return status */ unsigned short conn_channel; /* connect inet device i/o channel */ struct sockchar conn_sockchar; /* connect socket char buffer */ unsigned int client_retlen; /* returned length of client socket */ /* address structure */ struct sockaddr_in client_addr; /* client socket address structure */ struct itemlst_3 client_itemlst; /* client item-list 3 descriptor */ char buf[] = "Hello, world!"; /* server data buffer */ int buflen = sizeof( buf ); /* length of server data buffer */ $DESCRIPTOR( inet_device, /* string descriptor with logical */ "SYS$NET" ); /* name of internet pseudodevice */ /* * init connection socket characteristics buffer */ conn_sockchar.prot = TCPIP$C_TCP; conn_sockchar.type = TCPIP$C_STREAM; conn_sockchar.af = TCPIP$C_AUXS; /* * init client's item-list descriptor */ memset( &client_itemlst, 0, sizeof(client_itemlst) ); client_itemlst.length = sizeof( client_addr ); client_itemlst.address = &client_addr; client_itemlst.retlen = &client_retlen; /* * init client's socket address structure */ memset( &client_addr, 0, sizeof(client_addr) ); /* * assign device socket */ status = sys$assign( &inet_device, /* device name */ &conn_channel, /* i/o channel */ 0, /* access mode */ 0 /* not used */ ); if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to assign i/o channel to TCPIP device\n" ); exit( status ); } /* * create connection socket */ status = sys$qiow( EFN$C_ENF, /* event flag */ conn_channel, /* i/o channel */ IO$_SETMODE, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ &conn_sockchar, /* p1 - socket char buffer */ 0, /* p2 */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to create socket\n" ); exit( status ); } /* * log this client connection */ status = sys$qiow( EFN$C_ENF, /* event flag */ conn_channel, /* i/o channel */ IO$_SENSEMODE, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ 0, /* p1 */ 0, /* p2 */ 0, /* p3 */ &client_itemlst, /* p4 - peer socket name */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to accept client connection\n" ); exit( status ); } printf( "Accepted connection from host: %s, port: %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port) ); /* * connection established with a client; * now attempt to write on this connection */ status = sys$qiow( EFN$C_ENF, /* event flag */ conn_channel, /* i/o channel */ IO$_WRITEVBLK, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ buf, /* p1 - buffer address */ buflen, /* p2 - buffer length */ 0, /* p3 */ 0, /* p4 */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to write data to client connection\n" ); exit( status ); } printf( "Data sent: %s\n", buf ); /* output server's data buffer */ /* * close connection socket */ status = sys$qiow( EFN$C_ENF, /* event flag */ conn_channel, /* i/o channel */ IO$_DEACCESS, /* i/o function code */ &iosb, /* i/o status block */ 0, /* ast service routine */ 0, /* ast parameter */ 0, /* p1 */ 0, /* p2 */ 0, /* p3 */ TCPIP$C_DSC_ALL, /* p4 - discard all packets */ 0, /* p5 */ 0 /* p6 */ ); if ( status & STS$M_SUCCESS ) status = iosb.status; if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to close socket\n" ); exit( status ); } /* * deassign device socket */ status = sys$dassgn( conn_channel ); if ( !(status & STS$M_SUCCESS) ) { printf( "Failed to deassign i/o channel to TCPIP device\n" ); exit( status ); } exit( EXIT_SUCCESS ); } |
This section contains the following examples:
Example E-7 shows how a typical UDP IPv4 client uses the Sockets API to handle the tasks of creating a socket, writing server data, and deleting the socket.
Example E-7 UDP Client (Sockets API) |
---|
#pragma module tcpip$udp_client_sock \ "V5.1-00" /* * Copyright 2000 Compaq Computer Corporation * * COMPAQ Registered in U.S. Patent and Trademark Office. * * Confidential computer software. Valid license from Compaq * or authorized sublicensor required for possession, use or * copying. Consistent with FAR 12.211 and 12.212, Commercial * Computer Software, Computer Software Documentation, and * Technical Data for Commercial Items are licensed to the * U.S. Government under vendor's standard commercial license. * * ++ * FACILITY: * * EXAMPLES * * ABSTRACT: * * This is an example of a UDP/IP IPv4 client using 4.x BSD * socket Application Programming Interface (API) to handle * network I/O operations. * * Refer to 'Build, Configuration, and Run Instructions' for * details on how to build, configure, and run this program. * * ENVIRONMENT: * * OpenVMS Alpha/VAX V7.1 * TCP/IP Services V5.0 or higher * * AUTHOR: * * TCPIP Development Group, CREATION DATE: 23-May-1989 * * -- */ /* Build, Configuration, and Run Instructions */ /* * BUILD INSTRUCTIONS: * * To build this example program use commands of the form, * * using the DEC "C" compiler: * * $ cc/prefix=all TCPIP$UDP_CLIENT_SOCK.C * $ link TCPIP$UDP_CLIENT_SOCK * * using the DEC "C++" compiler: * * $ cxx/prefix=all/define=VMS TCPIP$UDP_CLIENT_SOCK.C * $ link TCPIP$UDP_CLIENT_SOCK * * * CONFIGURATION INSTRUCTIONS: * * No special configuration required. * * * RUN INSTRUCTIONS: * * To run this example program: * * 1) Start the client's server program as shown below: * * $ run tcpip$udp_server_sock * Waiting for a client datagram on port: m * * 2) After the server program blocks, start this client program, * entering the server host as shown below: * * $ run tcpip$udp_client_sock * Enter remote host: * * Note: You can specify a server host by using either an IPv4 * address in dotted-decimal notation (e.g. 16.20.10.56) * or a host domain name (e.g. serverhost.compaq.com). * * 3) The client program then displays server address information * and server data as show below: * * Sent a datagram to host: a.b.c.d, port: n * Data sent: Hello, world! * * You can enter "ctrl/z" at any user prompt to terminate program * execution. * */ /* * INCLUDE FILES: */ #include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <inet.h> /* define network address info */ #include <netdb.h> /* define network database library info */ #include <socket.h> /* define BSD 4.x socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #include <unixio.h> /* define unix i/o */ /* * NAMED CONSTANTS: */ #define BUFSZ 1024 /* user input buffer size */ #define SERV_PORTNUM 12345 /* server port number */ /* * FORWARD REFERENCES: */ int main( void ); /* client main */ void get_serv_addr( void * ); /* get server host address */ /* Client Main */ /* * FUNCTIONAL DESCRIPTION: * * This is the client's main-line code. It handles all the tasks of the * client including: socket creation, writing server data, and deleting * the socket. * * This example program implements a typical UDP IPv4 client using the * BSD socket API to handle network i/o operations as shown below: * * 1) To create a socket: * * socket() * * 2) To transfer data: * * sendto() * * 3) To close a socket: * * close() * * This function is invoked by the DCL "RUN" command (see below); the * function's completion status is interpreted by DCL and if needed, * an error message is displayed. * * SYNOPSIS: * * int main( void ) * * FORMAL PARAMETERS: * * ** None ** * * IMPLICIT INPUTS: * * ** None ** * * IMPLICIT OUTPUTS: * * ** None ** * * FUNCTION VALUE: * * completion status * * SIDE EFFECTS: * * ** None ** * */ int main( void ) { int sockfd; /* udp socket descriptor */ char buf[] = "Hello, World!"; /* client data buffer */ struct sockaddr_in serv_addr; /* server socket address structure */ /* * init server's socket address structure */ memset( &serv_addr, 0, sizeof(serv_addr) ); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons( SERV_PORTNUM ); get_serv_addr( &serv_addr.sin_addr ); /* * create udp socket */ if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } /* * write datagram to server */ if ( sendto(sockfd, buf, sizeof(buf), 0, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) { perror( "Failed to write datagram to server" ); exit( EXIT_FAILURE ); } printf( "Sent a datagram to host: %s, port: %d\n", inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port) ); printf( "Data sent: %s\n", buf ); /* output data buffer */ /* * close udp socket */ if ( close(sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } /* Get Server Host Address */ /* * FUNCTIONAL DESCRIPTION: * * This function gets the server host's address from the user and then * stores it in the server's socket address structure. Note that the * user can specify a server host by using either an IPv4 address in * dotted-decimal notation (e.g. 16.20.10.126) or a host domain name * (e.g. serverhost.compaq.com). * * Enter "ctrl/z" to terminate program execution. * * SYNOPSIS: * * void get_serv_addr( void *addrptr ) * * FORMAL PARAMETERS: * * addrptr - pointer to socket address structure's 'sin_addr' field * to store the specified network address * * IMPLICIT INPUTS: * * ** None ** * * IMPLICIT OUTPUTS: * * ** None ** * * FUNCTION VALUE: * * ** None ** * * SIDE EFFECTS: * * Program execution is terminated if unable to read user's input. * */ void get_serv_addr( void *addrptr ) { char buf[BUFSZ]; struct in_addr val; struct hostent *host; while ( TRUE ) { printf( "Enter remote host: " ); if ( fgets(buf, sizeof(buf), stdin) == NULL ) { printf( "Failed to read user input\n" ); exit( EXIT_FAILURE ); } buf[strlen(buf)-1] = 0; val.s_addr = inet_addr( buf ); if ( val.s_addr != INADDR_NONE ) { memcpy( addrptr, &val, sizeof(struct in_addr) ); break; } if ( (host = gethostbyname(buf)) ) { memcpy( addrptr, host->h_addr, sizeof(struct in_addr) ); break; } } } |
E.3.2 UDP Server
Example E-8 shows how a typical UDP IPv4 server uses the Sockets API
to handle the tasks of creating a socket, binding a socket to the
server's internet address and port, and reading client data.
Example E-8 UDP Server (Sockets API) |
---|
#pragma module tcpip$udp_server_sock \ "V5.1-00" /* * Copyright 2000 Compaq Computer Corporation * * COMPAQ Registered in U.S. Patent and Trademark Office. * * Confidential computer software. Valid license from Compaq * or authorized sublicensor required for possession, use or * copying. Consistent with FAR 12.211 and 12.212, Commercial * Computer Software, Computer Software Documentation, and * Technical Data for Commercial Items are licensed to the * U.S. Government under vendor's standard commercial license. * * ++ * FACILITY: * * EXAMPLES * * ABSTRACT: * * This is an example of a UDP/IP IPv4 server using 4.x BSD * socket Application Programming Interface (API) to handle * network I/O operations. * * Refer to 'Build, Configuration, and Run Instructions' for * details on how to build, configure, and run this program. * * ENVIRONMENT: * * OpenVMS Alpha/VAX V7.1 * TCP/IP Services V5.0 or higher * * AUTHOR: * * TCPIP Development Group, CREATION DATE: 23-May-1989 * * -- */ /* Build, Configuration, and Run Instructions */ /* * BUILD INSTRUCTIONS: * * To build this example program use commands of the form, * * using the DEC "C" compiler: * * $ cc/prefix=all TCPIP$UDP_SERVER_SOCK.C * $ link TCPIP$UDP_SERVER_SOCK * * using the DEC "C++" compiler: * * $ cxx/prefix=all/define=VMS TCPIP$UDP_SERVER_SOCK.C * $ link TCPIP$UDP_SERVER_SOCK * * * CONFIGURATION INSTRUCTIONS: * * No special configuration required. * * * RUN INSTRUCTIONS: * * To run this example program: * * 1) Start this server program server as shown below: * * $ run tcpip$udp_server_sock * Waiting for a client datagram on port: m * * 2) After the server program blocks, start the client program, * entering the server host as shown below: * * $ run tcpip$udp_client_sock * Enter remote host: * * Note: You can specify a server host by using either an IPv4 * address in dotted-decimal notation (e.g. 16.20.10.56) * or a host domain name (e.g. serverhost.compaq.com). * * 3) The server program then displays client address information * and client data as show below: * * Received a datagram from host: a.b.c.d, port: n * Data received: Hello, world! * * You can enter "ctrl/z" at any user prompt to terminate program * execution. * */ /* * INCLUDE FILES: */ #include <in.h> /* define internet related constants, */ /* functions, and structures */ #include <inet.h> /* define network address info */ #include <netdb.h> /* define network database library info */ #include <socket.h> /* define BSD 4.x socket api */ #include <stdio.h> /* define standard i/o functions */ #include <stdlib.h> /* define standard library functions */ #include <string.h> /* define string handling functions */ #include <unixio.h> /* define unix i/o */ /* * NAMED CONSTANTS: */ #define SERV_PORTNUM 12345 /* server port number */ /* * FORWARD REFERENCES: */ int main( void ); /* server main */ /* Server Main */ /* * FUNCTIONAL DESCRIPTION: * * This is the server's main-line code. It handles all the tasks of the * server including: socket creation, binding a socket to the server's * internet address and port, and reading client data. * * This example program implements a typical UDP IPv4 server using the * BSD socket API to handle network i/o operations as shown below: * * 1) To create a socket: * * socket() * * 2) To set REUSEADDR socket option: * * setsockopt() * * 3) To bind internet address and port number to a socket: * * bind() * * 4) To transfer data: * * recvfrom() * * 5) To close a socket: * * close() * * This function is invoked by the DCL "RUN" command (see below); the * function's completion status is interpreted by DCL and if needed, * an error message is displayed. * * SYNOPSIS: * * int main( void ) * * FORMAL PARAMETERS: * * ** None ** * * IMPLICIT INPUTS: * * ** None ** * * IMPLICIT OUTPUTS: * * ** None ** * * FUNCTION VALUE: * * completion status * * SIDE EFFECTS: * * ** None ** * */ int main( void ) { char buf[512]; /* server data buffer */ int optval = 1; /* SO_REUSEADDR'S option value (on) */ int sockfd; /* socket descriptor */ unsigned int client_addrlen; /* returned length of client socket */ /* address structure */ struct sockaddr_in client_addr; /* client socket address structure */ struct sockaddr_in serv_addr; /* server socket address structure */ /* * init client's socket address structure */ memset( &client_addr, 0, sizeof(client_addr) ); /* * init server's socket address structure */ memset( &serv_addr, 0, sizeof(serv_addr) ); serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons( SERV_PORTNUM ); serv_addr.sin_addr.s_addr = INADDR_ANY; /* * create a udp socket */ if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { perror( "Failed to create socket" ); exit( EXIT_FAILURE ); } /* * bind server's internet address and port number to socket */ if ( setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0 ) { perror( "Failed to set socket option" ); exit( EXIT_FAILURE ); } if ( bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 ) { perror( "Failed to bind socket" ); exit( EXIT_FAILURE ); } /* * read datagram from client */ printf( "Waiting for a client datagram on port: %d\n", ntohs(serv_addr.sin_port) ); client_addrlen = sizeof(client_addr); if ( recvfrom(sockfd, buf, sizeof(buf), 0, (struct sockaddr *) &client_addr, &client_addrlen) < 0 ) { perror( "Failed to read datagram from client" ); exit( EXIT_FAILURE ); } printf( "Received a datagram from host: %s, port: %d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port) ); printf( "Data received: %s\n", buf ); /* output client's data buffer */ /* * close udp socket */ if ( close(sockfd) < 0 ) { perror( "Failed to close socket" ); exit( EXIT_FAILURE ); } exit( EXIT_SUCCESS ); } |
Previous | Next | Contents | Index |