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

Previous | Contents | Index

# 2.7 Getting Socket Options

Obtaining socket information is useful if your program has management functions, or if you have a complex program that uses multiple connections you need to track.

## 2.7.1 Getting Socket Information (Sockets API)

You can use any of the following Sockets API functions to get socket information:

- `getpeername()`
- `getsockname()`
- `getsockopt()`

Example 2-11 shows a TCP server using the `getpeername()` function to get the remote IP address and port number associated with a socket.

Example 2-11 Getting Socket Information (Sockets API)

    #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 socket api                */
    #include <stdio.h>                  /* define standard i/o functions        */
    #include <stdlib.h>                 /* define standard library functions    */
    #include <string.h>                 /* define string handling functions     */

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

    int main( void )
    {
        int conn_sockfd;                    /* connection socket descriptor     */
        int listen_sockfd;                  /* listen socket descriptor         */

        unsigned int cli_addrlen;           /* returned length of client socket */
                                            /* address structure                */
        struct sockaddr_in cli_addr;        /* client socket address structure  */
        struct sockaddr_in serv_addr;       /* server socket address structure  */

        /*
         * initialize 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 listen socket
         */

        if ( (listen_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
            {
            perror( "Failed to create socket" );
            exit( EXIT_FAILURE );
            }
        /*
         * bind server's ip address and port number to listen socket
         */

        if ( bind(listen_sockfd,
                  (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
            {
            perror( "Failed to bind socket" );
            exit( EXIT_FAILURE );
            }

        /*
         * set socket as a listen socket
         */

        if ( listen(listen_sockfd, SERV_BACKLOG) < 0 )
            {
            perror( "Failed to set socket passive" );
            exit( EXIT_FAILURE );
            }

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

        conn_sockfd = accept( listen_sockfd, (struct sockaddr *) 0, 0 );

        if ( conn_sockfd < 0 )
            {
            perror( "Failed to accept client connection" );
            exit( EXIT_FAILURE );
            }

        /*
         * log client connection request
         */

        cli_addrlen = sizeof(cli_addr);
        memset( &cli_addr, 0, sizeof(cli_addr) );

        if ( getpeername(conn_sockfd (1),
                         (struct sockaddr * ) &cli_addr, (2) &cli_addrlen (3)) < 0 )
            {
            perror( "Failed to get client name" );
            exit( EXIT_FAILURE );
            }

        printf( "Accepted connection from host: %s, port: %d\n",
                inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port) (4)
              );

        exit( EXIT_SUCCESS );
    }

1. `conn_sockaddr` is the socket descriptor returned by the previous call to the `accept()` function.
2. `cli_addr` is the address structure for the connected socket.
3. `cli_addrlen` is the length of the address structure for the connected socket.
4. The `printf` statement accesses the information stored in the address structure for the connected socket and displays the client's IP address and port number. The `inet_ntoa ()` and the `ntohs()` functions are used to convert the IP address and port number from their network byte order to the host byte order.

## 2.7.2 Getting Socket Information (System Services)

To obtain information about the parts of a socket, use the $QIO system service with IO$_SENSEMODE to get socket information.

Example 2-12 shows a TCP client using the IO$_SENSEMODE function to get the client's IP address and port number.

Example 2-12 Getting Socket Information (System Services)

    #include <descrip.h>                /* define OpenVMS descriptors           */
    #include <efndef.h>                 /* define 'EFN$C_ENF' event flag        */
    #include <in.h>                     /* define internet related constants,   */
    <valid_break>
                                        /* 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            */

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

    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           */
        unsigned short prot;                /* protocol                         */
        unsigned char type;                 /* type                             */
        unsigned char af;                   /* address format                   */
        };

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

        unsigned short listen_channel;      /* listen inet device i/o channel   */
        struct sockchar listen_sockchar;    /* listen socket characteristics    */

        unsigned int cli_addrlen;           /* returned length of client socket */
                                            /* address structure                */
        struct sockaddr_in cli_addr;        /* client socket address structure  */
        struct itemlst_3 cli_itemlst;       /* client socket address item-list  */

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

        $DESCRIPTOR( inet_device,           /* string descriptor with logical   */
                     "TCPIP$DEVICE:" );     /* name of network pseudodevice     */
        /*
         * initialize socket characteristics
         */

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

        /*
         * initialize client's item-list descriptor
         */

        cli_itemlst.length  = sizeof( cli_addr );
        cli_itemlst.type    = TCPIP$C_SOCK_NAME;
        cli_itemlst.address = &cli_addr;
        cli_itemlst.retlen  = &cli_addrlen;

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

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

        /*
         * initialize 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 i/o channels to network device
         */

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

        /*
         * bind server's ip address and port number to 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                */
                           0,                   /* p1                           */
                           0,                   /* p2                           */
                           &serv_itemlst,       /* p3 - local socket name       */
                           0,                   /* p4                           */
                           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 );
            }
        /*
         * set socket as 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                */
                           0,                   /* p1                           */
                           0,                   /* p2                           */
                           0,                   /* p3                           */
                           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 set socket passive\n" );
            exit( status );
            }

        /*
         * accept 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                           */
                           0,                   /* p3                           */
                           &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 );
            }

        /*
         * log client connection request
         */

        memset( &cli_addr, 0, sizeof(cli_addr) );

        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                           */
                           &cli_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 get client name\n" );
            exit( status );
            }

        printf( "Accepted connection from host: %s, port: %d\n",
                inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port)
              );

        exit( EXIT_SUCCESS );
    }

# 2.8 Setting Socket Options

With TCP/IP Services, you use the `setsockopt()` function to set binary socket options and socket options that return a value. Calls to `setsockopt()` specifying unsupported options return an error code of `ENOPROTOOPT` .

## 2.8.1 Setting Socket Options (Sockets API)

Example 2-13 shows a TCP server using the `setsockopt ()` function to set the `SO_REUSEADDR` option.

Example 2-13 Setting Socket Options (Sockets API)

    #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 socket api                */
    #include <stdio.h>                  /* define standard i/o functions        */
    #include <stdlib.h>                 /* define standard library functions    */
    #include <string.h>                 /* define string handling functions     */

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

    int main( void )
    {
        int optval = 1;                     /* SO_REUSEADDR's option value (on) */

        int conn_sockfd;                    /* connection socket descriptor     */
        int listen_sockfd;                  /* listen socket descriptor         */

        unsigned int cli_addrlen;           /* returned length of client socket */
                                            /* address structure                */
        struct sockaddr_in cli_addr;        /* client socket address structure  */
        struct sockaddr_in serv_addr;       /* server socket address structure  */

        /*
         * initialize 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 listen socket
         */

        if ( (listen_sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
            {
            perror( "Failed to create socket" );
            exit( EXIT_FAILURE );
            }

        /*
         * bind server's ip address and port number to listen socket
         */

        if ( setsockopt(listen_sockfd,  (1)
             SOL_SOCKET (2)
    , SO_REUSEADDR (3)
    , &optval (4)
    , sizeof(optval) (5)
    ) < 0 )
            {
            perror( "Failed to set socket option" );
            exit( EXIT_FAILURE );
            }

        if ( bind(listen_sockfd,
                  (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0 )
            {
            perror( "Failed to bind socket" );
            exit( EXIT_FAILURE );
            }

        /*
         * set socket as a listen socket
         */
        if ( listen(listen_sockfd, SERV_BACKLOG) < 0 )
            {
            perror( "Failed to set socket passive" );
            exit( EXIT_FAILURE );
            }

        /*
         * accept connection from a client
         */

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

        conn_sockfd = accept( listen_sockfd, (struct sockaddr *) 0, 0 );

        if ( conn_sockfd < 0 )
            {
            perror( "Failed to accept client connection" );
            exit( EXIT_FAILURE );
            }

        /*
         * log client connection request
         */

        cli_addrlen = sizeof(cli_addr);
        memset( &cli_addr, 0, sizeof(cli_addr) );

        if ( getpeername(conn_sockfd,
                         (struct sockaddr *) &cli_addr, &cli_addrlen) < 0 )
            {
            perror( "Failed to get client name" );
            exit( EXIT_FAILURE );
            }

        printf( "Accepted connection from host: %s, port: %d\n",
                inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port)
              );

        exit( EXIT_SUCCESS );
    }

1. `listen_sockfd` refers to an open socket descriptor returned by the previous call to the `socket ()` function.
2. `SOL_SOCKET` specifies the code in the system to interpret the option. In this case, the level is the general socket code.
3. `SO_REUSEADDR` is the socket option to be set. In this case, the socket option allows reuse of local addresses.
4. `optval` is the value to set for the option. In this case, the value is 1, which enables the option.
5. `sizeof(optval)` is the size of the option value.

## 2.8.2 Setting Socket Options (System Services)

Example 2-14 shows how to set socket options using $QIO system services.

Example 2-14 Setting Socket Options (System Services)

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

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

    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           */
        unsigned short prot;                /* protocol                         */
        unsigned char type;                 /* type                             */
        unsigned char af;                   /* address format                   */
        };

    int main( void )
    {
        int optval = 1;                     /* reuseaddr option value (on)      */

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

        unsigned int cli_addrlen;           /* returned length of client socket */
                                            /* address structure                */
        struct sockaddr_in cli_addr;        /* client socket address structure  */
        struct itemlst_3 cli_itemlst;       /* client socket address item-list  */

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

        struct itemlst_2 sockopt_itemlst;   /* server socket option item-list   */
        struct itemlst_2 reuseaddr_itemlst; /* reuseaddr option item-list       */
        $DESCRIPTOR( inet_device,           /* string descriptor with logical   */
                     "TCPIP$DEVICE:" );     /* name of network pseudodevice     */

        /*
         * initialize socket characteristics
         */

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

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

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

        /*
         * initialize setsockopt's item-list descriptor
         */

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

        /*
         * initialize client's item-list descriptor
         */

        cli_itemlst.length  = sizeof( cli_addr );
        cli_itemlst.type    = TCPIP$C_SOCK_NAME;
        cli_itemlst.address = &cli_addr;
        cli_itemlst.retlen  = &cli_addrlen;

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

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

        /*
         * initialize 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 i/o channels to network device
         */
        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)\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 characteristics  */
                           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 );
            }

        /*
         * bind server's ip address and port number to 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                */
                           0,                   /* p1                           */
                           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 set socket option\n" );
            exit( status );
            }

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

        /*
         * set socket as 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                */
                           0,                   /* p1                           */
                           0,                   /* p2                           */
                           0,                   /* p3                           */
                           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 set socket passive\n" );
            exit( status );
            }

        /*
         * accept 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                           */
                           0,                   /* p3                           */
                           &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 );
            }
        /*
         * log client connection request
         */

        memset( &cli_addr, 0, sizeof(cli_addr) );

        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                           */
                           &cli_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 get client name\n" );
            exit( status );
            }

        printf( "Accepted connection from host: %s, port: %d\n",
                inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port)
              );

        exit( EXIT_SUCCESS );
    }

Previous | Next | Contents | Index