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


Previous Contents Index


IO$_WRITEVBLK

Write I/O functions provide direct transfer of data from the virtual address space of the user's process to an internet host or port. The DIGITAL TCP/IP Services for OpenVMS product provides the WRITE I/O function code IO$_WRITEVBLK, which writes a user buffer for stream sockets, datagrams, or raw IP.

If you specify multiple buffers, the system sends data from buffers in the order specified by the p5 list. For UDP and raw IP, the TCP/IP software sends the data in one datagram. The data to be sent is buffered by TCP/IP before being transmitted to the remote host.

For a TCP socket, if the socket transmit queue is full, the Write I/O operation will be blocked until the transmit queue has enough room for the user data.

For UDP and raw IP sockets, if the user data is greater than the transmit (send) socket quota, an error code is returned (SS$_TOOMUCHDATA).

The equivalent C Socket functions are send(), sendto(), sendmsg(), and write().

Programming examples for the IO$_WRITEVBLK routine follow this command description. Example 4-12 uses the MACRO-32 programming language and Example 4-13 uses the C programming language to read a vectored buffer. Example 4-14 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 containing the data to be transmitted.

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 containing the data to be transmitted.

p3


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

The p3 argument specifies the address of an item_list_2 descriptor. This descriptor points to a buffer that contains the remote port and remote host internet address (socket name) of the message destination.

p4


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

The p4 argument specifies the flags for the Write operation. Table 4-18 describes the valid flags for this argument.

Table 4-18 Valid Write Flags for the p4 Argument
Flag Description
TCPIP$C_MSG_OOB Writes an out-of-band (OOB) byte.
TCPIP$C_MSG_DONTROUTE Sends the message directly without routing.
TCPIP$C_MSG_NBIO Completes the I/O operation and returns an error if a condition arises that would cause the I/O operation to be blocked. Similar to using IO$M_NOWAIT.

p5


usage item_list_2
type quadword unsigned (Alpha); longword unsigned (VAX)
access read only
mechanism by descriptor

The p5 argument specifies the address for the descriptor of an input parameter list. The maximum number of buffers you can specify with the p5 argument is 16.

The p1 and p2 arguments and the p5 argument are mutually exclusive. You either use p1 and p2 or you use p5. The software first checks to see if the p1 argument is being used. If p1 is not used, it checks to see if the p5 argument is being used. If neither the p1 nor the p5 argument is being used, an error code is produced.

The resulting transfer-length value of the I/O status block is the sum of the bytes transferred in the multiple buffers.


Function Modifiers

IO$M_INTERRUPT Sends an out-of-band byte to a target process. At the remote process, the byte is delivered to the user through the data receive mechanism.
IO$M_NOWAIT Regardless of a $QIO or $QIOW, if the system detects a condition that would cause the I/O operation to be blocked, the system completes the I/O operation and returns the error code SS$_SUSPENDED.

When using this function modifier, always check the message length in the IOSB to ensure that all data is transferred. If only 1 byte of data is transferred, the function returns a success status even if data is not completely transferred.


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. An attempt was made to access an invalid memory location or buffer.
SS$_BADPARAM Programming error. A $QIO I/O function was specified using an invalid parameter.
  1. An attempt was made to execute an IO$_WRITEVBLK function without specifying a device socket. First create a device socket by issuing an IO$_SETMODE function and the proper arguments.
  2. An attempt was made to issue an IO$_READVBLK or IO$_WRITEVBLK function that does not specify a correct buffer address ( p1, p5, or p6 is null).
  3. An attempt was made to issue an IO$_READVBLK or IO$_WRITEVBLK that specifies an invalid vectored buffer ( p5 or p6 specifies an invalid address descriptor).
SS$_CANCEL Warning code. The I/O operation was canceled by issuing a $CANCEL system service.
SS$_DEVINACT INET management error. The driver was not started. A before issuing any $QIO function.
SS$_DEVNOTMOUNT INET management error. The INET startup procedure was executed improperly. The driver was loaded, but the INET_ACP was not activated.
SS$_EXQUOTA Returned when process resource mode wait is disabled. There is no internet request packet (IRP) available for completing the request. Increase the buffered I/O quota.
SS$_FILALRACC Programming error.
  1. INET address is already in use. An attempt was made to bind the socket to an address but the port failed.
  2. IP protocol (raw socket). An attempt was made to specify a remote INET socket address with an IO$_WRITEVBLK function, while an INET address was already specified with an IO$_ACCESS function.
  3. UDP/IP protocol. An attempt was made to specify a remote INET socket address with an IO$_WRITEVBLK function, while an INET address was already specified with the IO$_ACCESS function.
SS$_ILLCNTRFUNC Programming error. Unsupported operation on the protocol (IP, UDP/IP, TCP/IP).
SS$_INSFMEM INET management or programming error returned when process resource mode wait is disabled. Not enough system space for buffering user data. A higher quota for socket buffer space needs to be set, or the internet needs more dynamic buffer space (number of dynamic clusters should be increased).
SS$_IVADDR Programming error. The specified INET address is not in the system, and an invalid port number or an INET address combination was specified with an IO$_WRITEVBLK operation.
  1. An attempt to bind the socket failed because the INET address is not in the system, port number zero and INET address zero are not allowed, or port zero is not allowed with an IO$_ACCESS or IO$_WRITEVBLK function.
  2. An attempt to get an interface INET address, broadcast mask, or network mask failed.
  3. A send request was made on a datagram-oriented protocol, but the destination address is unknown or not specified.
SS$_IVBUFLEN Programming error.
  1. The size of the buffer for an I/O function is insufficient.
  2. An attempt was made to issue an IO$_WRITEVBLK function that specifies a correct buffer address ( p1 valid), but does not specify a buffer length ( p2 is null).
SS$_LINKDISCON Notification. Connection completion return code. The virtual circuit (TCP/IP) was closed at the initiative of the peer. The application must stop sending data and shutdown or close the socket.
SS$_PROTOCOL Programming error. The address family of the remote INET address specified with an IO$_WRITEVBLK function is not supported (UDP/IP or TCP/IP). The address family should be the TCPIP$C_AF_INET address family.
SS$_NOLINKS Programming error. The socket was not connected (TCP/IP) or an INET port and address were not specified with an IO$_ACCESS (UDP/IP or IP).
  1. An IO$_WRITEVBLK with no remote INET socket address was issued on a socket that was not the object of an IO$_ACCESS function (raw IP).
  2. An IO$_WRITEVBLK with no remote INET socket address was issued on a socket that was not the object of an IO$_ACCESS function (UDP/IP).
  3. An attempt was made to disconnect a socket that is not connected, or an attempt was made to issue an IO$_WRITEVBLK or IO$_READVBLK function on an unconnected socket (TCP/IP).
SS$_SHUT The network is being shut down.
SS$_SUSPENDED The operation was blocked. A send operation requires system buffer space that is not available. The socket is marked as performing nonblocking operations.
SS$_TIMEOUT Programming error, INET management error, or hardware error.
  1. A TCP/IP connection timed out after several unsuccessful retransmissions.
  2. On a TCP socket where KEEPALIVE is set, the connection was idle for longer than the timeout interval (10 minutes by default).
SS$_TOOMUCHDATA Programming or INET management error. The message size was too large.
  1. An IP packet that is broadcast cannot be fragmented.
  2. The Not Fragment IP flag was set and the IP datagram was too large to be sent without being fragmented.
  3. Internal error. The length of the Ethernet datagram does not allow enough space for the minimum IP header.
  4. The message to be sent on a UDP/IP or raw IP socket is larger than the socket buffer high water allows.
  5. An attempt was made to send or receive more than 16 buffers specified with the p5 argument.
SS$_UNREACHABLE Programming error. Either the network address is invalid or the network is unreachable.

Hardware error. The data link adapter detected an error and shut itself off. The TCP/IP Services software is waiting for the adapter to come back on line.

Example 4-12 IO$_WRITEVBLK Function (MACRO-32 Programming)

 
        .title write 
        .ident  /01/ 
; 
; Write a vectored buffer 
; 
 
        $inetsymdef                     ; INET symbols 
 
dev:    .ascid  /tcpip$device:/                   ; INET device name 
channel:        .word   0               ; INET channel 
iostatus:       .quad   0               ; I/O status block 
; 
; INET Socket address definition of the remote host 
; 
Ret_adr: 
        .word   INET$C_AF_INET          ; INET family 
        .word   5002                    ; Port number 
                                        ; Remote host IP address 
        .byte   128,20,20               ; Network/subnetwork number 
        .byte   156                     ; Remote Host number 
        .blkb   8 
Ret_len=.-Ret_adr 
leng:   .long   0              ; Return length of Remote IP address 
; 
; INET Socket address definition of the local host 
; 
Local_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                      ; Local Host number 
        .blkb   8 
par11:  .word   INET$C_UDP              ; UDP/IP  protocol 
        .word   INET_PROTYP$C_DGRAM     ; Datagram type of socket 
; 
; Item_list_2 descriptor for the Remote IP address 
; 
par12:  .long   ret_len                 ; Length 
        .address ret_adr                ; Buffer address 
; 
; Item_list_2 descriptor for the Local IP address 
; 
par13:  .long   ret_len                 ; Length 
        .address local_adr              ; Address 
; 
; I/O Buffer 
; 
buffer: 
        .blkb   512 
buflen=.-buffer 
 
        .entry   start,^m<> 
        . 
        . 
        . 
; 
; Perform a QIOW write operation 
; 
write: 
        $qiow_s efn=#31,-               ; Event flag 
                chan=channel, -         ; Channel 
                func=#io$_writevblk,-   ; I/O function 
                iosb= iostatus,-        ; I/O status 
                p1=buffer,-             ; I/O Buffer address 
                p2=#buflen,-            ; I/O Buffer length 
                p3=#par12               ; Address of Descriptor 
                                        ; of buffer of the remote 
                                        ; Host IP address 
        blbc    r0,exit                 ; Branch if error 
        movzwl  iostatus,r0             ; 
        blbc    r0,exit                 ; 
        $dassgn_s       chan=Channel    ; Deassign the socket device 
exit: 
        ret                             ; Exit 
        .end start 
 

Example 4-13 IO$_WRITEVBLK Function --- Vectored (C Programming)

 
#module write_vecio 
/* 
**++ 
**      
** This example does vectored buffers write 
** 
**-- 
*/ 
 
 
/* 
**  INCLUDE FILES 
*/ 
 
#include <descrip.h> 
#include <tcpip$inetdef.h>     /* INET symbol definitions */ 
#include <iodef.h> 
 
/* 
** 
*/ 
 
struct bvec              /* Structure definition for vec buf */ 
        { 
          int lenth ; 
          char *b_adrs ; 
        } ; 
 
struct sockaddr {            /* Structure definition for socket adrs */ 
        short inet_family ; 
        short inet_port ; 
        char adrs[4] ; 
        char blkb[8] ; 
       } ; 
 
struct itlst { 
        int lgth ; 
        struct sockaddr *hst ; 
         } ; 
           
main() 
 
{ 
     int status ;            /* For return status */ 
     short channel ;         /* INET channel */ 
     short sck_parm[2] ;     /* Socket creation parameter */ 
     int iosb [2] ;          /* I/O status block           */ 
     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 = 
            { 3, DSC$K_CLASS_S, DSC$K_DTYPE_T, "TCPIP$DEVICE:"} ;     
 
 
/* Descriptor for vectored buffer */ 
 
        struct dsc$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 = 0 ;          /* Port number */ 
       remote_host.adrs[0] = 128 ;          /* Network/subnetwork*/ 
       remote_host.adrs[1] = 45 ;           /*  number */ 
       remote_host.adrs[2] = 45 ; 
       remote_host.adrs[3] = 175 ;          /* 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 = INET$C_AF_INET ;/* INET family */ 
       local_host.inet_port = 0 ;          /* Port number */ 
       local_host.adrs[0] = 128 ;          /* Network/subnetwork*/ 
       local_host.adrs[1] = 45 ;           /*  number */ 
       local_host.adrs[2] = 45 ; 
       local_host.adrs[3] = 186 ;          /* 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 device socket \n") ; 
            return(status) ; 
       } 
/* 
** Perform the QIO write operation 
*/ 
        status = SYS$QIOW( 31,          /* Event flag */ 
                           channel,    /* Channel number */ 
                           IO$_WRITEVBLK,/* I/O function */ 
                  iosb,                 /* I/O status block */ 
                  0, 
                  0, 
                  0,          
                  0, 
                  &rhst_adrs,          /* P3 Remote host adrs desc */ 
                  0, 
                  &buf_d,              /* P5 Vectored buffer desc */ 
                  0) ; 
        if ((status & 1) == 0) { 
            printf("Failed to write to socket \n") ; 
            return(status) ; 
        } 
/* 
** Deassign the INET dev channel 
*/ 
        SYS$DASSGN (channel); 
 
        return(status) ; 
} 

Example 4-14 IO$_WRITEVBLK Function (C Programming)

 
#module write_io 
/* 
**++ 
**      
** This example does writes to INET device 
** 
**-- 
*/ 
 
 
/* 
**  INCLUDE FILES 
*/ 
 
#include <descrip.h> 
#include <tcpip$inetdef.h>   /* INET symbol definitions */ 
#include <iodef.h> 
 
struct sockaddr {          /* Structure definition for socket adrs */ 
        short inet_family ; 
        short inet_port ; 
        char adrs[4] ; 
        char blkb[8] ; 
       } ; 
 
struct itlst { 
     int lgth ; 
     struct sockaddr *hst ; 
      } ;           
main() 
 
{ 
     int status ;            /* For return status */ 
     short channel           /* INET channel */ 
     short sck_parm[2] ;     /* Socket creation parameter */ 
     int iosb [2] ;          /* I/O status block           */ 
     struct sockaddr local_host ; /* Socket adrs definition for lhst */ 
     struct itlst lhst_adrs ; 
     char buf[128] ; 
     int buflen = 128 ; 
     
/* Descriptor for Inet device name */ 
 
        struct dsc$descriptor dev = 
            { 3, DSC$K_CLASS_S, DSC$K_DTYPE_T, "TCPIP$DEVICE:"} ;     
 
/* 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 ; 
/* 
** 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) ; 
          } 
/* Initialize socket address for local host */ 
 
       local_host.inet_family = INET$C_AF_INET ;/* INET family */ 
       local_host.inet_port = 0 ;               /* Port number */ 
       local_host.adrs[0] = 128 ;               /* Network/subnetwork*/ 
       local_host.adrs[1] = 45 ;                /*  number */ 
       local_host.adrs[2] = 45 ; 
       local_host.adrs[3] = 216 ;               /* 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 ; 
/* 
** 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 device socket \n") ; 
            return(status) ; 
          } 
/* 
** Perform the QIO write operation 
*/ 
 
     status = SYS$QIOW( 0,          /* Event flag */ 
                        channel,    /* Channel number */ 
                        IO$_WRITEVBLK,/* I/O function */ 
                        iosb,       /* I/O status block */ 
                        0, 
                        0, 
                        buf,          /* P1 buffer */          
                        buflen,0,0,0,0);/* P2 buffer length */ 
        if ((status & 1) == 0) { 
            printf("Failed to write to INET device \n") ; 
            return(status) ; 
     } 
/* 
** Deassign the INET dev channel 
*/ 
        SYS$DASSGN (channel); 
 
        return(status) ; 
 
} 
 


Previous Next Contents Index