HP OpenVMS Systems Documentation

Content starts here

Compaq TCP/IP Services for OpenVMS
Sockets API and System Services Programming


Previous Contents Index

E.2.2 TCP Server

Example E-5 shows how a typical TCP IPv4 server uses $QIO system services to handle the tasks of creating a socket, accepting or rejecting client connections, writing client connection data, and then terminating client connections.

Example E-5 TCP Server (System Services)


#pragma module  tcpip$tcp_server_qio                    \
                "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.
 *
 *    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.C
 *      $ link TCPIP$TCP_SERVER_QIO
 *
 *    using the DEC "C++" compiler:
 *
 *      $ cxx/prefix=all/define=VMS TCPIP$TCP_SERVER_QIO.C
 *      $ link TCPIP$TCP_SERVER_QIO
 *
 *
 * CONFIGURATION INSTRUCTIONS:
 *
 *    No special configuration required.
 *
 *
 * RUN INSTRUCTIONS:
 *
 *    To run this example program:
 *
 *    1) Start this server program as shown below:
 *
 *       $ run tcpip$tcp_server_qio
 *       Waiting for a client connection on port: m
 *
 *    2) After the server program blocks, start the client program,
 *       entering the server host as shown below:
 *
 *       $ run tcpip$tcp_client_qio
 *       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 connection information
 *       and client data as shown below:
 *
 *       Accepted connection from 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 <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 <netdb.h>                  /* define network database library info */

#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            */


/*
 * NAMED CONSTANTS:
 */

#define SERV_BACKLOG    1               /* server backlog                   */
#define SERV_PORTNUM    12345           /* server port number               */


/*
 * 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, accepting and/or rejecting client
 *    connections, 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 as shown below:
 *
 *      1) To create a socket and set REUSEADDR option:
 *
 *         sys$assign() and sys$qiow(IO$_SETMODE)
 *
 *      2) To bind internet address and port number to a socket:
 *
 *         sys$qiow(IO$_SETMODE)
 *
 *      3) To accept a connection request:
 *
 *         sys$qiow(IO$_ACCESS|IO$M_ACCEPT)
 *
 *      4) To transfer data:
 *
 *         sys$qiow(IO$_WRITEVBLK)
 *
 *      5) To shutdown a socket:
 *
 *         sys$qiow(IO$_DEACCESS|IO$M_SHUTDOWN)
 *
 *      6) 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 )
{
    int one = 1;                        /* reuseaddr option value           */

    struct iosb iosb;                   /* i/o status block                 */

    unsigned int status;                /* system service return status     */

    unsigned short conn_channel;        /* connect inet device i/o channel  */
    unsigned short listen_channel;      /* listen inet device i/o channel   */

    struct sockchar listen_sockchar;    /* listen 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    */

    struct sockaddr_in serv_addr;       /* server socket address structure  */
    struct itemlst_2 serv_itemlst;      /* server item-list 2 descriptor    */

    struct itemlst_2 sockopt_itemlst;   /* sockopt item-list 2 descriptor   */
    struct itemlst_2 reuseaddr_itemlst; /* reuseaddr item-list 2 element    */

    char buf[] = "Hello, World!";       /* server data buffer               */
    int  buflen = sizeof( buf );        /* length of server data buffer     */

    $DESCRIPTOR( inet_device,           /* string descriptor with logical   */
                 "TCPIP$DEVICE" );      /* name of internet pseudodevice    */

    /*
     * init listen socket characteristics buffer
     */

    listen_sockchar.prot = TCPIP$C_TCP;
    listen_sockchar.type = TCPIP$C_STREAM;
    listen_sockchar.af   = TCPIP$C_AF_INET;

    /*
     * init reuseaddr's item-list element
     */

    reuseaddr_itemlst.length  = sizeof( one );
    reuseaddr_itemlst.type    = TCPIP$C_REUSEADDR;
    reuseaddr_itemlst.address = &one;

    /*
     * init sockopt's item-list descriptor
     */

    sockopt_itemlst.length  = sizeof( reuseaddr_itemlst );
    sockopt_itemlst.type    = TCPIP$C_SOCKOPT;
    sockopt_itemlst.address = &reuseaddr_itemlst;

    /*
     * 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) );

    /*
     * init server's item-list descriptor
     */

    serv_itemlst.length  = sizeof( serv_addr );
    serv_itemlst.type    = TCPIP$C_SOCK_NAME;
    serv_itemlst.address = &serv_addr;

    /*
     * init server's socket address structure
     */

    memset( &serv_addr, 0, sizeof(serv_addr) );
    serv_addr.sin_family      = TCPIP$C_AF_INET;
    serv_addr.sin_port        = htons( SERV_PORTNUM );
    serv_addr.sin_addr.s_addr = TCPIP$C_INADDR_ANY;

    /*
     * assign device sockets
     */

    status = sys$assign( &inet_device,      /* device name                  */
                         &listen_channel,   /* i/o channel                  */
                         0,                 /* access mode                  */
                         0                  /* not used                     */
                       );

    if ( (status & STS$M_SUCCESS) )
        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(s) to TCPIP device\n" );
        exit( status );
        }

    /*
     * create a listen socket
     */

    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       listen_channel,      /* i/o channel                  */
                       IO$_SETMODE,         /* i/o function code            */
                       &iosb,               /* i/o status block             */
                       0,                   /* ast service routine          */
                       0,                   /* ast parameter                */
                       &listen_sockchar,    /* p1 - socket char buffer      */
                       0,                   /* p2                           */
                       0,                   /* p3                           */
                       0,                   /* p4                           */
                       &sockopt_itemlst,    /* p5 - socket options          */
                       0                    /* p6                           */
                     );

    if ( status & STS$M_SUCCESS )
        status = iosb.status;

    if ( !(status & STS$M_SUCCESS) )
        {
        printf( "Failed to create socket\n" );
        exit( status );
        }

    /*
     * bind server's internet address and port number to
     * listen socket; set socket as a passive socket
     */

    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       listen_channel,      /* i/o channel                  */
                       IO$_SETMODE,         /* i/o function code            */
                       &iosb,               /* i/o status block             */
                       0,                   /* ast service routine          */
                       0,                   /* ast parameter                */
                       0,                   /* p1                           */
                       0,                   /* p2                           */
                       &serv_itemlst,       /* p3 - local socket name       */
                       SERV_BACKLOG,        /* p4 - connection backlog      */
                       0,                   /* p5                           */
                       0                    /* p6                           */
                     );

    if ( status & STS$M_SUCCESS )
        status = iosb.status;

    if ( !(status & STS$M_SUCCESS) )
        {
        printf( "Failed to bind socket\n" );
        exit( status );
        }

    /*
     * accept a connection from a client
     */

    printf( "Waiting for a client connection on port: %d\n",
            ntohs(serv_addr.sin_port)
          );

    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       listen_channel,      /* i/o channel                  */
                       IO$_ACCESS|IO$M_ACCEPT,
                                            /* i/o function code            */
                       &iosb,               /* i/o status block             */
                       0,                   /* ast service routine          */
                       0,                   /* ast parameter                */
                       0,                   /* p1                           */
                       0,                   /* p2                           */
                       &client_itemlst,     /* p3 - remote socket name      */
                       &conn_channel,       /* p4 - i/o channel for new     */
                                            /*      connection              */
                       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  */

    /*
     * shutdown connection socket
     */

    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       conn_channel,        /* i/o channel                  */
                       IO$_DEACCESS|IO$M_SHUTDOWN,
                                            /* 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 shutdown client connection\n" );
        exit( status );
        }

    /*
     * 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                           */
                       0,                   /* p4                           */
                       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 );
        }
    /*
     * close listen socket
     */

    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       listen_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                           */
                       0,                   /* p4                           */
                       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 all device sockets
     */

    status = sys$dassgn( conn_channel );

    if ( (status & STS$M_SUCCESS) )
        status = sys$dassgn( listen_channel );

    if ( !(status & STS$M_SUCCESS) )
        {
        printf( "Failed to deassign i/o channel(s) to TCPIP device\n" );
        exit( status );
        }

    exit( EXIT_SUCCESS );
}

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


Previous Next Contents Index