hp.com home products and services support and drivers solutions how to buy
cd-rom home
End of Jump to page title
HP OpenVMS systems
documentation

Jump to content


HP TCP/IP Services for OpenVMS

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


Previous Contents Index

This example show how to:

  1. Create a socket using the IO$M_SETMODE service.
  2. Bind the socket using the IO$M_SETMODE service, specifying parameter p3.
  3. Set the socket to passive mode using the IO$M_SETMODE service, specifying parameter p4.
  4. Accept an incoming connection using the IO$_ACCESS|IO$_ACCEPT service.

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:

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

This example obtains the remote IP address and port number using the getpeername() function and then prints the information.

  1. conn_sockfd 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 network byte order to 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 the IO$_SENSEMODE function.

Example 2-12 shows a TCP service using the IO$_SENSEMODE function to get a 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) ); 
(1)
    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 ); 
} 

This example show how to use the $QIOW system service to obtain remote port information.

  1. The IO$_SENSEMODE service returns the port number and IP address in the structure defined by p4.

2.8 Setting Socket Options

To set binary socket options and socket options that return a value, use the setsockopt() Sockets API function or the IO$_SETMODE system service.

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

This example uses the setsockopt() function to allow local addresses to be reused.

  1. listen_sockfd refers to an open socket descriptor returned by the previous call to the socket () function.
  2. SOL_SOCKET specifies that the options will be modified at socket level.
  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.

Calls to setsockopt() specifying unsupported options return an error code of ENOPROTOOPT .

2.8.2 Setting Socket Options (System Services)

Example 2-14 shows how to set socket options using 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                           */ 
                (1)     &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