DIGITAL TCP/IP Services for OpenVMS
System Services and C Socket Programming


Previous Contents Index


IO$_DEACCESS

The IO$_DEACCESS function closes a connection. You can use a flag to specify whether pending I/O operations will be completed or discarded before the function is completed. After the function completes, $QIOs to transmit data are no longer allowed. To resume transmitting on the channel being used, you must issue the appropriate functions to initialize a communication link. If it is required for the protocol, you must also issue $QIOs with IO$_SETMODE, and if it is required for the protocol, IO$_ACCESS as well.

Issuing an IO$_DEACCESS function disconnects the link between the two communicating agents previously established with an IO$_ACCESS function. The connection is discontinued, but messages queued for transmission are sent to the connection peer before finally disconnecting the link.

An IO$_DEACCESS function prevents the user process that issued the function from sending any more data. It also ensures successful delivery of all data queued before the IO$_DEACCESS function was issued, unless there is a fatal error. A fatal error will be signaled. The user may continue to receive data until it is signaled that the connection peer has closed the connection.

Before a receiving process with a connection-oriented protocol is notified about a synchronous disconnection, all the data that the peer sent is received.

You can specify a wait time or time-to-linger socket parameter (TCPIP$C_LINGER option) for transmission completion before disconnecting the connection. Use the IO$_SETMODE or IO$_SETCHAR function to set and clear the TCPIP$C_LINGER option.

If you set the TCPIP$C_LINGER option, a $QIO call that uses the IO$_DEACCESS function allows data queued to the socket to arrive at the destination. The system is blocked until data arrives at the remote socket. The socket data structure remains open for the duration of the TCP idle time interval.

If you do not set the TCPIP$C_LINGER option (option is set to 0), a $QIO call that uses the IO$_DEACCESS function discards any data queued to the socket and deallocates the socket data structure.

Note

For compatibility with UNIX TCP/IP, the TCP/IP Services implementation of TCP/IP forces a time-to-linger of 2 minutes on stream sockets.

The equivalent C Socket function is close() or shutdown().


Arguments

p4


usage flags
type byte (unsigned)
access read only
mechanism by value

This argument is used only with the IO$M_SHUTDOWN function modifier. The following table lists the IO$M_SHUTDOWN flags (defined in the TCPIP$INETDEF symbol definition file) that you can use to specify the disposition of pending I/O operations.
Shutdown Flag Description
TCPIP$C_DSC_RCV Discards messages from the receive queue and disallows further receiving. Pending messages in the receive queue for this connection are discarded. The socket is put in CANTRCVMORE state.
TCPIP$C_DSC_SND Discards messages from the send queue and disallows further sending. Pending messages in the transmit queue for this connection are discarded. The socket is put in CANTSNDMORE state.
TCPIP$C_DSC_ALL Discards all messages and disallows both sending and receiving (socket is put in the CANTRCVMORE and CANTSNDMORE states). All pending messages are discarded. Specifying this flag has the same effect as issuing a $CANCEL function followed by an IO$_DEACCESS function without any flags.

Function Modifiers

IO$M_SHUTDOWN Causes all or part of the full-duplex connection on the device socket to be shut down. The p4 parameter specifies shutdown flags.
IO$M_NOW Regardless of a $QIO or $QIOW, if the system detects a condition that would cause the I/O operation to block, the system completes the I/O operation and returns the error code SS$_SUSPENDED.

Condition Values Returned

SS$_ABORT Programming error, INET management error, or hardware error. The execution of the I/O function aborts. A disconnect was requested on a connection that already started a disconnect operation.
SS$_BADPARAM Programming error. You specified a $QIO function using an invalid parameter. You tried to execute one of the I/O functions without specifying a device socket. Instead, you should first create a device socket by issuing a $QIO with the IO$_SETMODE function and the proper parameters.
SS$_CANCEL Warning code. The I/O operation canceled by executing a $CANCEL system service routine.
SS$_DEVINACT INET management error. The driver was not started. You must execute a START COMMUNICATION command before issuing a $QIO operation.
SS$_DEVNOTMOUNT INET management error. You improperly executed the INET startup procedure. The driver was loaded, but the INET_ACP function was not activated.
SS$_NOLINKS Programming error because of one of the following reasons:
  1. The socket was not connected (TCP/IP) or an INET port and address were not specified with an IO$_ACCESS (UDP/IP) or IP.
  2. You tried to disconnect an unconnected socket.
SS$_SHUT The network is being shut down.

IO$_READVBLK

Read functions transfer data received from an internet host and store that data in system-dynamic space on the virtual memory address of the user process. The TCP/IP software provides the READ I/O function code IO$_READVBLK, which reads a virtual block of a stream socket, datagram, or raw socket.

Received messages are stored in system-dynamic memory and copied to user buffers when the software issues a read operation.

If you specify multiple buffers, the buffers are filled in the order specified in the p6 list.

The TCP/IP software fills in these user buffers according to the protocol (socket type).

For TCP/IP (stream socket), data is buffered in system space as a stream of bytes. The user buffer specified with a $QIO is filled in with data that is being buffered in system space. The I/O is completed when there is no more data in the system space, or there is no more available space in the user buffer. Data that is buffered in the system space but did not fit in the user buffer is available to the user in subsequent $QIOs. No data is discarded or lost.

Datagram and raw socket data is buffered in system space as a chain of records. The user buffer specified with a $QIO is filled in with data that is being buffered in one record in system space. One I/O operation reads data from one record. The I/O completes when there is no more space in the user buffer or when all data from the record has been transferred to the user buffer. Data remaining in the current record in system space that did not fit in the user buffer is discarded. A subsequent $QIO reads data from the next record buffered in system space.

Use the management command SHOW DEVICE_SOCKET /FULL to display counters related to read operations.

The equivalent C Socket function is the read(), recv(), recvfrom(), or recvmsg() routine.

Three programming examples for the IO$_READVBLK routine follow this command description. Example 4-9 uses the MACRO-32 programming language to read a vectored buffer. Example 4-10 uses the C programming language to read a vectored buffer. Example 4-11 uses the C programming language to read from an INET driver.


Arguments

p1


usage buffer
type quadword unsigned (Alpha); longword unsigned (VAX)
access read only
mechanism by reference

The p1 argument specifies the starting virtual address of the buffer that is to receive the data.

p2


usage buffer length
type quadword unsigned (Alpha); longword unsigned (VAX)
access read only
mechanism by value

The p2 argument specifies the size (in bytes) of the buffer that is to receive the data.

p3


usage remote socket name for the source of the message
type quadword unsigned (Alpha); longword unsigned (VAX)
access read only
mechanism by descriptor

The p3 argument specifies the address of an item_list_3 descriptor with a buffer that contains the remote socket name of the source of the UDP or raw IP message (not TCP). The remote socket is composed of the remote port and host internet address.

The parameter name for the descriptor is TCPIP$C_SOCK_NAME, which is defined in the TCPIP$INETDEF symbol definition file.

p4


usage flags
type word (unsigned)
access read only
mechanism by value

The p4 argument specifies the flags for the read operation. The valid flags are described in Table 4-8.

Table 4-8 Valid Flags for the p4 Argument
Flag Description
TCPIP$C_MSG_OOB Reads an out-of-band byte.
TCPIP$C_MSG_PEEK Reads a message but leaves the message in the queue. Another read operation shows the same message.
TCPIP$C_MSG_NBIO Does not block the I/O operation if the receive queue is empty. Similar to using IO$M_NOWAIT.
TCPIP$C_MSG_PURGE Flushes data from the queue. Similar to using IO$M_PURGE.
TCPIP$C_MSG_BLOCKALL Blocks the completion of the operation until the buffer is filled completely or until the connection is closed. Similar to using IO$M_LOCKBUF.

p6


usage item_list_2
type longword (unsigned)
access read only
mechanism by descriptor

The p6 argument specifies the address for the descriptor of an output parameter list.

The maximum number of buffers you can specify with the p6 argument is 16.

If you use the p1 and p2 arguments, do not use the p6 argument; they are mutually exclusive. You either use p1 and p2, or you use p6 instead. The software first checks to see if the p1 argument is used. If p1 is not used, the software checks to see if the p6 argument is being used. If neither the p1 nor the p6 arguments are used, the software returns an error code.

The transfer-length value returned in the I/O status block is the total number of bytes transferred to the buffer or multiple buffers.


Function Modifiers

IO$M_EXTEND Allows the use of extended modifiers with BSD Version 4.4. Valid only for datagram sockets (UDP or raw IP); ignored for TCP.

When used with the p3 parameter, indicates that the user wants the remote socket name that was the source of the received datagram to be returned in the buffer specified by p3. In this case, the setting of the IO$M_EXTEND modifier specifies the format of the remote socket name that is returned.

If the IO$_EXTEND bit is set, the remote socket name is returned in BSD Version 4.4 format. If the bit is clear, the remote socket name is returned in BSD Version 4.3 format. (Note that previous versions of the product followed the BSD Version 4.3 format.)

IO$M_INTERRUPT Reads an out-of-band (OOB) message. This has the same effect as specifying the TCPIP$C_MSG_OOB flag.
  On receiving a TCP/IP OOB character, TCP/IP stores the pointer in the received stream with the character that precedes the OOB character.
  A read operation with a user-buffer size larger than the size of the received stream up to the OOB character completes and returns to the user the received stream up to, but not including, the OOB character.
  To determine whether the socket must issue more read $QIOs before getting all the characters from the stream preceding an OOB character, poll the socket. To do this, issue a $QIO with the $IO_SENSEMODE function, and the TCPIP$C_IOCTL subfunction that specifies the SIOCATMARK command. The SIOCATMARK values are as follows:
  • 0 = Issue more read QIOs to read more data before reading the OOB.
  • 1 = The next read QIO will return the OOB.
  Polling a socket is particularly useful when the OOBINLINE socket option is set. When the OOBINLINE is set, TCP/IP reads the OOB character with the characters in the stream (IO$_READVBLK), but not before reading the preceding characters. Use this polling mechanism to determine whether the first character in the user buffer on the next read is an OOB character.
  On a socket with the OOBINLINE option set to clear, a received OOB will always be read by issuing a $QIO with either the IO$_READVBLK!IO$M_INTERRUPT or IO$_READVBLK and the TCPIP$C_MSG_OOB flag set. This can occur, regardless of how many preceding characters in the stream have been returned to the user.
IO$M_LOCKBUF Blocks the completion of the I/O operation until the user buffer is completely filled or until the connection is closed. This is particularly useful when you want to minimize the number of $QIO commands issued to read a data stream of a particular size. This function code is supported only for stream protocols.
IO$M_NOWAIT Regardless of a $QIO or $QIOW, if the system detects a condition that would cause the I/O operation to block, the system completes the I/O operation and returns the error code SS$_SUSPENDED.
IO$M_PURGE Flushes data from the device socket receive queue (discards data). If the user buffer is larger than the amount of data in the queue, all data in the queue is flushed. This function works in the same manner for both datagram and stream sockets.

Condition Values Returned

SS$_ABORT Programming error, INET management error, or hardware error. The execution of the I/O was aborted.
SS$_ACCVIO Programming error. You tried to access an invalid memory location or buffer.
SS$_BADPARAM Programming error. You used one of the following methods to specify a $QIO function with an invalid parameter:
  1. You executed an I/O function without specifying a device socket. You must first issue a $QIO with the IO$_SETMODE function and the proper parameters to create the device socket.
  2. You issued an IO$_READVBLK or IO$_WRITEVBLK function that does not specify a correct buffer address ( p1, p5 or p6 are null).
  3. You issued an IO$_READVBLK or IO$_WRITEVBLK function that specifies an invalid vectored buffer ( p5 or p6 are invalid address descriptors).
  4. The socket has the OOBINLINE option set, or there is no OOB character in the socket's OOB queue because the character was either already read or never received. This condition happens only if you use the IO$M_INTERRUPT modifier or set the TCPIP$C_MSG_OOB flag with IO$_READVBLK.
SS$_CANCEL Warning code. The I/O operation canceled by executing a $CANCEL system service routine.
SS$_CONNECFAIL Programming error, INET management error, or hardware error. The connection was abnormally terminated.
SS$_DEVINACT INET management error. The driver has not been started. You must execute the management command START COMMUNICATION before issuing a $QIO routine.
SS$_DEVNOTMOUNT INET management error. You improperly executed the INET startup procedure. The driver was loaded, but the INET_ACP was not activated.
SS$_INSFMEM INET management or programming error. There is not enough buffer space for allocation. The INET software needs more buffer space. You should set a higher quota for the dynamic buffer space, or shut down and restart your internet with a larger static buffer space.
SS$_IVBUFLEN Programming error occurred for one of the following reasons:
  1. The size of the buffer for an I/O function is insufficient.
  2. You tried to issue an IO$_READVBLK or IO$_WRITEVBLK that specifies a correct buffer address ( p1 valid), but does not specify a buffer length ( p2 is null).
SS$_LINKDISCON A virtual circuit (TCP/IP) was closed at the initiative of the peer.
SS$_NOLINKS Programming error. Read attempt on unconnected TCP socket.
SS$_SHUT The network is being shut down.
SS$_SUSPENDED The operation is blocked for one of the following reasons:
  1. No messages were received so the receive operation cannot complete. The socket is marked as nonblocking.
  2. The socket has the OOBINLINE option clear, and the OOB character has already been read.
SS$_TIMEOUT This applies to a socket that has KEEPALIVE set. The connection was idle for longer than the timeout interval (10 minutes is the default).
SS$_UNREACHABLE Communication status. The remote host or network is unreachable.

Example 4-9 IO$_READVBLK Function (MACRO-32 Programming)

 
        .title Read_v 
;+ 
;       Read using a vectored buffer descriptor 
;- 
        .ident  /01/ 
 
        $inetsymdef             ; INET symbols 
 
dev:    .ascid  /tcpip$device:/           ; INET device name 
channel:        .word   0       ; INET channel 
iostatus:       .quad   0       ; I/O status block 
Ret_adr:        .blkb 16        ; Buffer for remote host IP address 
Ret_len=.-Ret_adr 
leng:   .long   0               ; Return length of Remote IP address 
loc_adr:.word   INET$C_AF_INET  ; INET family 
        .word   5001            ; Port number 
                                ; Local host IP address 
        .byte   128,20,20       ; Network/subnetwork number 
        .byte   10              ; Host number 
        .blkb   8 
par11:  .word   INET$C_UDP      ; UDP/IP  protocol 
        .word   INET_PROTYP$C_DGRAM  ; Datagram type of socket 
; 
; Item_list_3 descriptor for the Remote IP address 
; 
par12:  .long   ret_len         ; Length 
        .address ret_adr        ; Buffer address 
        .address leng           ; Returned length 
; 
; Item_list_2 descriptor for the Local IP address 
; 
par13:  .long   ret_len         ; Length 
        .address loc_adr        ; Address 
; 
; I/O Buffer 
; 
buffer_1: 
        .blkb   512 
buflen=.-buffer_1 
buffer_2: 
        .blkb   512 
buffer_3: 
        .blkb   512 
buffer_4: 
        .blkb   512 
buf_d:  .long   len_d 
        .address buffer_d 
buffer_d: 
        .long   buflen 
        .address buffer_1 
        .long   buflen 
        .address buffer_2 
        .long   buflen 
        .address buffer_3 
        .long   buflen 
        .address buffer_4 
len_d=.-buffer_d 
 
        .entry   start,^m<> 
; 
;       Assign an INET  device 
; 
        $assign_s       devnam=dev, chan=channel 
        blbs    r0,read 
        brw     exit 
; 
; Create and bind the device socket to the local host 
; 
read: 
        $qioW_s efn=#31,-               ; Event flag 
                chan=channel, -         ; Channel 
                func=#io$_setmode,-     ; I/O Function 
                iosb= iostatus, -       ; I/O status block 
                p1=par11,-              ; Socket creation parameters 
                P3=#Par13               ; Socket Bind parameters 
        blbc    r0,exit 
; 
; Perform a QIOW read operation 
; 
        $qiow_s efn=#31,-               ; Event flag 
                chan=channel, -         ; Channel 
                func=#io$_readvblk,-    ; I/O function 
                iosb= iostatus,-        ; I/O status 
                p3=#par12,-; Descriptor of the remote Host IP address 
                P6=#buf_d               ; Vectored buffer descriptor 
exit: 
        ret                             ; Exit 
 
        .end start 
 

Example 4-10 IO$_READVBLK Function --- Vectored Buffers (C Programming)

 
#module read_vecio 
/* 
**++ 
**      
** This example does vectored buffers read 
** 
**-- 
*/ 
 
 
/* 
**  INCLUDE FILES 
*/ 
 
#include <descrip.h> 
#include <tcpip$inetdef.h>     /* INET symbol definitions */ 
#include <iodef.h> 
 
/* 
** 
*/ 
 
struct bvec              /* Structure definition for vec buf */ 
          { 
            int length ; 
            char *b_adrs ; 
          } ; 
 
struct sockaddr {          /* Structure definition for socket adrs */ 
        short inet_family ; 
        short inet_port ; 
        char adrs[4] ; 
        char blkb[8] ; 
       } ; 
           
main() 
 
{ 
     int status ;          /* For return status */ 
     short channel ;       /* INET channel */ 
     short sck_parm[2] ;  /* Socket creation parameter */ 
     char buf_1[12],buf_2[12],buf_3[12],buf_4[12] ; 
     struct sockaddr remote_host ; /Socket adrs definition for rhst */ 
     struct sockaddr local_host ; /Socket adrs definition for lhst */ 
     struct itlst lhst_adrs ; 
     struct itlst rhst_adrs ; 
     struct bvec buf_vec[5] =     
          { 
          {12, &buf_1 }, 
          {12, &buf_2 }, 
          {12, &buf_3 }, 
          {12, &buf_4 }, 
          {0, 0 } 
          } ; 
 
/* Descriptor for Inet device name */ 
 
     struct dsc$descriptor dev = 
         { 11, DSC$K_CLASS_S, DSC$K_DTYPE_T, "TCPIP$DEVICE:"} ;     
 
 
/* Descriptor for vectored buffer */ 
 
     struct desc$descriptor buf_d = 
         { 0, DSC$K_CLASS_S, DSC$K_DTYPE_T, 0} ; 
 
/* Initialize the parameters */ 
 
        sck_parm[0] = INET$C_UDP ;     /* UDP/IP protocol */ 
        sck_parm[1] = INET_PROTYP$C_DGRAM ; /*Datagram type of socket*/ 
 
/* Itlst for local IP address */ 
 
        lhst_adrs.lgth = sizeof(local_host); 
        lhst_adrs.hst = &local_host ; 
 
        rhst_adrs.lgth = sizeof(remote_host) ; 
        rhst_adrs.hst = &remote_host ; 
 
        buf_d.dsc$a_pointer = buf_vec; 
        buf_d.dsc$w_length = sizeof(bvec) ; 
 
/* Initialize socket address for remote host */ 
 
       remote_host.inet_family = INET$C_AF_INET ; /* INET family */ 
       remote_host.inet_port = 5002 ;        /* Port number */ 
       remote_host.adrs[0] = 128 ;           /* Network/subnetwork*/ 
       remote_host.adrs[0] = 20 ;            /*  number */ 
       remote_host.adrs[0] = 20 ; 
       remote_host.adrs[0] = 156 ;             /* Host number */ 
       remote_host.blkb[0] = 0 ; 
       remote_host.blkb[1] = 0 ; 
       remote_host.blkb[2] = 0 ; 
       remote_host.blkb[3] = 0 ; 
       remote_host.blkb[4] = 0 ; 
       remote_host.blkb[5] = 0 ; 
       remote_host.blkb[6] = 0 ; 
       remote_host.blkb[7] = 0 ; 
 
/* Initialize socket address for local host */ 
 
       local_host.inet_family = AF_INET ;     /* INET family */ 
       local_host.inet_port = 5002 ;          /* Port number */ 
       local_host.adrs[0] = 128 ;             /* Network/subnetwork*/ 
       local_host.adrs[0] = 20 ;              /*  number */ 
       local_host.adrs[0] = 20 ; 
       local_host.adrs[0] = 156 ;             /* Host number */ 
       local_host.blkb[0] = 0 ; 
       local_host.blkb[1] = 0 ; 
       local_host.blkb[2] = 0 ; 
       local_host.blkb[3] = 0 ; 
       local_host.blkb[4] = 0 ; 
       local_host.blkb[5] = 0 ; 
       local_host.blkb[6] = 0 ; 
       local_host.blkb[7] = 0 ; 
 
/* 
** Assign a channel to INET device 
*/ 
          
        status = SYS$ASSIGN( &dev, 
                             &channel, 
                             0, 
                             0) ; 
         if ((status & 1) == 0) { 
            printf("Failed to assign channel to INET device \n") ; 
            return(status) ; 
             } 
     
/* 
** Create and bind the device socket to local host 
*/ 
 
        status = SYS$QIOW( 31,          /* Event flag */ 
                           channel,    /* Channel number */ 
                           IO$_SETMODE, /* I/O function */ 
                           iosb,        /* I/O status block */ 
                           0, 
                           0, 
                           &sck_parm, /* P1 Socket creation parameter */ 
                           0, 
                           &lhst_adrs, /* P3 Socket bind parameter */ 
                           0,0,0) ; 
        if ((status & 1) == 0) { 
            printf("Failed to create and bind the devicesocket \n") ; 
            return(status) ; 
 
/* 
** Perform the QIO read operation 
*/ 
 
     status = SYS$QIOW( 31,          /* Event flag */ 
                        channel,    /* Channel number */ 
                        IO$_READVBLK,/* I/O function */ 
                        iosb,        /* I/O status block */ 
                        0, 
                        0, 
                        0,          
                        0, 
                        &rhst_adrs,  /* P3 Remote host adrs desc */ 
                        0, 
                        0,     
                        &buf_d) ;   /* P6 Vectored buffer desc */ 
     if ((status & 1) == 0) { 
         printf("Failed to read from  device \n") ; 
         return(status) ; 
     } 
 
/* 
** Deassign the INET dev channel 
*/ 
        SYS$DASSGN (channel); 
 
        return(status) ; 
} 
 


Previous Next Contents Index