HP OpenVMS Systems Documentation

Content starts here

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


Previous Contents Index

  1. Structure setup for IO$_ACPCONTROL parameter p1.
  2. Address and size of buffer to receive network information.
  3. The first call to the IO$_ACPCONTROL service specifies the host name in argument p2.
  4. The second call to the IO$_ACPCONTROL service specifies the IP address in argument p2.

2.17 Closing and Deleting a Socket

Closing a socket means that the program can no longer transmit data. Depending on how you close the socket, the program can receive data until the peer program also closes the socket.

When a remote system closes a socket, notification is not immediate, and another thread can erroneously attempt to use the socket.

If you send data to a closed socket, you might not receive an appropriate error message. Set the TCPIP$FULL_DUPLEX_CLOSE socket option if you want to have your application notified of an error when it sends data on a socket that has already been closed by the peer.

When you delete a socket, all pending messages queued for transmission are sent to the receiving socket before closing the connection.

2.17.1 Closing and Deleting (Sockets API)

Example 2-26 shows a TCP application using the close() function to close and delete a socket.

Example 2-26 Closing and Deleting a Socket (Sockets API)


#include <socket.h>                 /* define BSD socket api                */
#include <stdio.h>                  /* define standard i/o functions        */
#include <stdlib.h>                 /* define standard library functions    */
#include <unixio.h>                 /* define unix i/o                      */


int main( void )
{
    int sockfd;

    /*
     * create a socket
     */

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

    /*
     * close socket
     */

    if ( close(sockfd) < 0 )  (1)
        {
        perror( "Failed to close socket" );
        exit( EXIT_FAILURE );
        }

    exit( EXIT_SUCCESS );
}

This example creates and closes a socket.

  1. The sockfd argument for the close() function closes the socket and deletes the socket descriptor previously defined by the socket() function.

2.17.2 Closing and Deleting (System Services)

Example 2-27 shows a TCP application using $QIO system services to close and delete a socket.

Example 2-27 Closing and Deleting a Socket (System Services)


#include <descrip.h>                /* define OpenVMS descriptors           */
#include <efndef.h>                 /* define 'EFN$C_ENF' event flag        */
#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 <stsdef.h>                 /* define condition value fields        */
#include <tcpip$inetdef.h>          /* define tcp/ip network constants,     */
                                    /* structures, and functions            */

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 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 channel;             /* network device i/o channel       */
    struct sockchar sockchar;           /* socket characteristics buffer    */
    $DESCRIPTOR( inet_device,           /* string descriptor with logical   */
                 "TCPIP$DEVICE:" );     /* name of network pseudodevice     */

    /*
     * initialize socket characteristics
     */

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

    /*
     * assign i/o channel to network device
     */

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

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

    /*
     * create a socket
     */
    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       channel,             /* i/o channel                  */
                       IO$_SETMODE,         /* i/o function code            */
                       &iosb,               /* i/o status block             */
                       0,                   /* ast service routine          */
                       0,                   /* ast parameter                */
                       &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 );
        }

    /*
     * close socket
     */
(1)
    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       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 i/o channel to network device
     */

(2)  status = sys$dassgn( channel );

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

    exit( EXIT_SUCCESS );
}

This example closes the socket using the IO$_DEACCESS service and deletes it with the $DASSGN service.

  1. The IO$_DEACCESS service stops transmitting data and closes the socket.
  2. The $DASSGN service deletes the network device and deassigns the I/O channel previously acquired with the $ASSIGN service.

2.18 Shutting Down Sockets

You can shut down a socket before closing and deleting it. The shutdown operation allows you to shut down communication one process at a time. This maintains unidirectional rather than the normal bidirectional connections, allowing you to shut down communications on receive or transmit data queues, or both. For example, if you no longer want to transmit data but want to continue receiving data, shut down the transmit side of the socket connection and keep open the receive side.

2.18.1 Shutting Down a Socket (Sockets API)

Example 2-28 shows a TCP application using the shutdown() function.

Example 2-28 Shutting Down a Socket (Sockets API)


#include <socket.h>                 /* define BSD socket api                */
#include <stdio.h>                  /* define standard i/o functions        */
#include <stdlib.h>                 /* define standard library functions    */
#include <unixio.h>                 /* define unix i/o                      */


int main( void )
{
    int sockfd;

    /*
     * create a socket
     */

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

    /*
     * shutdown a socket
     */

(1)  if ( shutdown(sockfd, 2 ) < 0 )
        {
        perror( "Failed to shutdown socket connections" );
        exit( EXIT_FAILURE );
        }

    /*
     * close socket
     */
(2)
    if ( close(sockfd) < 0 )
        {
        perror( "Failed to close socket" );
        exit( EXIT_FAILURE );
        }

    exit( EXIT_SUCCESS );
}

This example shows how to use the shutdown() function to shut down a socket.

  1. The shutdown() function calls the socket descriptor ( sockfd ). The corresponding values are:
    • 0---Closes the receive socket queue.
    • 1---Shuts down the socket.
    • 2---Closes both the transmit and receive socket queues.
  2. The close() function then closes the socket and deletes the socket descriptor.

2.18.2 Shutting Down a Socket (System Services)

Example 2-29 shows a TCP server using the IO$_DEACCESS function with the IO$M_SHUTDOWN function modifier to shut down all communications. In this example, no data is received or transmitted and all queued data is discarded.

Example 2-29 Shutting Down a Socket (System Services)


#include <descrip.h>                /* define OpenVMS descriptors           */
#include <efndef.h>                 /* define 'EFN$C_ENF' event flag        */
#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 <stsdef.h>                 /* define condition value fields        */
#include <tcpip$inetdef.h>          /* define tcp/ip network constants,     */
                                    /* structures, and functions            */

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 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 channel;             /* network device i/o channel       */
    struct sockchar sockchar;           /* socket characteristics buffer    */
    $DESCRIPTOR( inet_device,           /* string descriptor with logical   */
                 "TCPIP$DEVICE:" );     /* name of network pseudodevice     */

    /*
     * initialize socket characteristics
     */

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

    /*
     * assign i/o channel to network device
     */

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

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

    /*
     * create a socket
     */
    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       channel,             /* i/o channel                  */
                       IO$_SETMODE,         /* i/o function code            */
                       &iosb,               /* i/o status block             */
                       0,                   /* ast service routine          */
                       0,                   /* ast parameter                */
                       &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 );
        }

    /*
     * shutdown a socket
     */

    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       channel,             /* i/o channel                  */
               (1)      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                           */
               (2)      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 socket connections\n" );
        exit( status );
        }

    /*
     * close socket
     */
    status = sys$qiow( EFN$C_ENF,           /* event flag                   */
                       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 i/o channel to network device
     */

    status = sys$dassgn( channel );

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

    exit( EXIT_SUCCESS );
}

This example shuts down a socket without completing pending I/O operations.

  1. To shut down a socket, use the IO$_DEACCESS service with the IO$M_SHUTDOWN modifier. This shuts down all or part of the full-duplex connection on the socket.
  2. In p4, the TCPIP$C_DSC_ALL flag specifies that pending I/O operations be discarded.

After the IO$_DEACCESS service completes, messages can no longer be transmitted or received on the socket.

2.19 Canceling I/O Operations

The $CANCEL system service cancels pending I/O requests on a specific channel Or socket. This includes all I/O requests queued and in progress.

There is no Sockets API function for this operation; the Sockets API library functions are synchronous.


Previous Next Contents Index