This chapter describes the Transmission Control Protocol (TCP) device driver (TCPDRIVER) services. It describes the user interface of this implementation of TCP only. RFC 793 contains the full TCP specifications. There are no implementation-specific restrictions for the Transmission Control Protocol (TCP). The material presented here does not explain or describe the TCP protocol.
TCP is a connection-oriented, end-to-end reliable protocol. It provides reliable communication between pairs of processes in computers attached to interconnected networks. TCP services are available through the OpenVMS Queue I/O (SYS$QIO and SYS$QIOW) system services, which:
· Open and close a connection.
· Send and receive data over the connection.
· Perform status checks on the connection.
SYS$QIOW is the synchronous and SYS$QIO the asynchronous form of VMS system services. Use each form depending on the requirements of your application.
See the appropriate OpenVMS documentation for more information on the OpenVMS I/O system services and related services, such as the asynchronous system trap (AST) and event flag services.
Note: The QIO calls described in this chapter are used for direct access to the TCPDRIVER. If you are porting an application that uses the BGDRIVER or INETDRIVER QIO interface, you may not need to make modifications. Use TCPware's BGDRIVER (see Chapter 2) or INETDRIVER (see Chapter 6).
|
The sequence of operations to open a connection are as follows:
1. Assign an I/O channel to TCP0: with the Assign I/O Channel (SYS$ASSIGN) system service. SYS$ASSIGN creates a new device unit and assigns to it the channel.
2. Open the connection with the IO$_SETMODE | IO$M_CTRL | IO$M_STARTUP function of one of the Queue I/O (SYS$QIO or SYS$QIOW) system services.
3. Perform read requests with the IO$_READVBLK function and write requests using the IO$_WRITEVBLK function as desired.
4. Close your end of the connection with the IO$_SETMODE | IO$M_CTRL | IOM$_SHUTDOWN function.
5. Perform additional read requests until the peer returns SS$_VCCLOSED status.
6. Deassign the I/O channel using the Deassign I/O Channel (SYS$DASSGN) system service.
In addition to the sequence of operations described in the preceding section, TCPDRIVER includes other operations that:
Place a connection into listen state and specify the maximum number of incoming connections that can be queued waiting to be accepted, then wait for and accept an incoming connection |
IO$_CREATE |
Read data immediately |
IO$_READVBLK | IO$M_NOW |
Read the received data without removing it from the received data queue |
IO$_READVBLK | IO$M_DATACHECK |
Read only completely filled data buffers |
IO$READVBLK | IO$M_PACKED |
Send data stored in a list of buffers |
IO$_WRITEVBLK | IO$M_EXTEND |
Read the active connections status |
IO$_SENSEMODE |
Read the connection characteristics for the channel |
IO$_SENSEMODE | IO$M_CTRL |
Read the TCP counters |
IO$_SENSEMODE | IO$M_RD_COUNT |
Set the connection characteristics |
IO$_SETMODE | IO$M_CTRL |
Request delivery of an attention AST |
IO$_SETMODE | IO$M_ATTNAST |
Abort a connection |
IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN | IO$M_ABORT |
Cancel any pending I/O requests |
SYS$CANCEL |
The format for the TCPDRIVER SYS$QIO system service call is as follows:
status = SYS$QIO(u_long efn, u_int chan, u_int func, unsinged quadword *iosb, void *astadr, u_long astprm, p1, p2, p3, p4, p5, p6)
The SYS$QIO or SYS$QIOW system calls issue TCP functions. SYS$QIO is for asynchronous service completion. It specifies that the service return to the caller immediately after queuing the I/O request. SYS$QIOW is for synchronous service completion. It specifies that the service place the calling process in a wait state and only return to the caller after completing the I/O operation. The OpenVMS IODEF module provides definitions for the SYS$QIO function codes.
Note: The vertical bar ( | ) used in some of the functions described in this chapter is the C bit-wise inclusive OR operator.
|
You invoke TCPDRIVER system service calls with the standard OpenVMS QIO mechanism.
See the appropriate OpenVMS documentation (for example, the Introduction to VMS System Services volume) for more information on the QIO mechanism.
The following sections describe each system call argument.
efn
Number of the event flag set by completion of the I/O operation. The argument is optional.
chan
I/O channel assigned to the TCP device to which you are directing the request.
func
Device-specific function code and the modifier if appropriate for each operation. Each func is described in the TCPDRIVER System Service Call Function Codes section.
iosb
I/O status block that receives the final completion status of the I/O operation. Structured as in the below figure. The following table describes the status block fields in detail.
Field Name |
Description |
Function-Specific |
Varies for each function code. |
Status Code |
The SS$ status code or special error status code. If the low bit (0) of the OpenVMS error code is clear, the network has returned an error. |
Transfer Byte Count |
Number of bytes of data transferred in the I/O operation. |
astadr
Address of the asynchronous system trap (AST) routine executed when the I/O is completed.
astprm
AST parameter to be passed to the AST routine.
p1…p6
Function-specific parameters, as described for each function.
System service call function codes specify what action the QIO performs. This section describes the TCPDRIVER function codes.
Provides for socket style listens and accepts.
Use the IO$_CREATE function to perform one of three operations:
ACCEPT |
Accept an incoming connection |
ACCEPT-WAIT |
Wait for an incoming connection |
LISTEN |
Place a connection into listen state and specify the maximum number of incoming connections that can be queued waiting to be accepted |
A typical flow for a program using this function might be as follows:
1. Assign a channel to the TCP: device (SYS$ASSIGN). This is the listening channel.
2. Issue an IO$_SETMODE | IO$M_CTRL function on the listening channel to specify the local port number for the service.
3. Issue an IO$_CREATE function on the listening channel to specify a large backlog (greater than 128 is recommended).
4. Issue an IO$_CREATE function (with all parameters set to zero) on the listening channel to await an incoming connection. (You could alternatively use an asynchronous QIO and AST routine). This function blocks until a connection is available.
5. Assign a channel to the TCP: device (SYS$ASSIGN) and issue an IO$_CREATE | IO$M_NOW function on the listening channel with newchan being the newly assigned channel.
6. The newly assigned channel (step 5) has the accepted connection and should be serviced (reads and writes).
7. Loop back to step 4 to continue accepting connections.
Ideally, steps 4 through 7 should be designed such that multiple connections can be serviced simultaneously.
status = SYS$QIO(efn, chan, IO$_CREATE, iosb, astadr, astprm, 0, 0, 0, backlog, 0, 0);
This function places the connection into a listen state. If you did not previously specify a local port number for the channel (see the IO$_SETMODE | IO$M_CTRL function), a unique port number is automatically assigned. The function completes execution immediately as it does not wait for an incoming connection.
p4 = u_int backlog
Connection backlog, or maximum number of connections that can be queued. It is recommended that you specify a large backlog (greater than 128) for most applications.
SS$_DEVINACT |
Device not
active |
SS$_FILALRACC |
Port is busy |
SS$_ILLIOFUNC |
Invalid parameters or modifiers were specified (returned in status, not in iosb) |
SS$_NORMAL |
Success |
status = SYS$QIO(efn, chan, IO$_CREATE, iosb, astadr, astprm, 0, 0, 0, 0, 0, 0);
This function waits for an incoming connection to be available on a listening connection. A listen function as specified in the LISTEN operation above must have been previously issued. You can use the IO$M_NOW modifier to probe if a connection is available; SS$_NODATA is returned if no connection is available.
SS$_DEVINACT |
Device not in
listen state or not active |
SS$_NODATA |
No connection
is currently available to be accepted |
SS$_NORMAL |
Success |
SS$_THIRDPARTY |
TCPDRIVER was shut down by a third party |
status = SYS$QIO(efn, chan, IO$_CREATE | IO$M_NOW, iosb, astadr, astprm, 0, 0, newchan, 0, 0, 0);
This function accepts an incoming connection. A listen function as specified in the LISTEN operation above must have been previously issued on the channel (chan). As this function does not block, a wait should generally precede it for an incoming connection function, as specified in the ACCEPT-WAIT operation above.
p3 = u_int newchan
OpenVMS channel for a newly created TCP: device. This channel should be created by using SYS$ASSIGN to assign a new channel to the TCP0: device before issuing this function. The accepted connection uses this channel.
SS$_DEVACTIVE |
I/O channel
specified in newchan is not inactive |
SS$_DEVINACT |
Connection is
not in listen state or the device is not active |
SS$_IVDEVNAM |
I/O channel specified in newchan is not a TCP: device |
SS$_NODATA |
No connection is available to accept |
Receives data, including urgent data, writing the received data to the specified user buffer.
The IO$M_DATACHECK modifier peeks at the next received data without removing it from the received data queue.
The IO$M_NOW modifier executes the function immediately regardless of the amount of available data. If no data is available, the function returns the SS$_NODATA status.
The IO$M_PACKED modifier requests that IO$_READVBLK return completely filled data buffers. IO$_READVBLK completes reads with this modifier only after receiving the requested number of bytes, unless the port closes or you specify IO$M_NOW.
Note: Use the IO$M_PACKED modifier with caution, as the read request only completes execution after receiving the requested number of bytes, or if the connection is closed or reset by the peer.
|
status = SYS$QIO(efn, chan, IO$_READVBLK, iosb, astadr, astprm, buffer, size, 0, 0, 0, 0);
p1 = byte *buffer
Address of the user's buffer that receives the data.
p2 = u_int size
User's buffer size in bytes. Specifies the maximum amount of data written to the buffer. The value should not be greater than 64000 bytes.
SS$_CANCEL |
Request canceled |
SS$_DEVINACT |
Device not
active |
SS$_NODATA |
No data available and IO$M_NOW was specified. |
SS$_NORMAL |
Success |
SS$_PATHLOST |
Route to peer
lost |
SS$_THIRDPARTY |
Connection
broken by third party |
SS$_TIMEOUT |
Connection
timed-out |
SS$_VCBROKEN |
Connection broken (either locally or by source) and closed |
SS$_VCCLOSED |
Peer closed end of the connection and no more data is available, or the connection was never opened |
The number of bytes received is returned in the high-order word of the first longword of the I/O status block. This may be less than the number of bytes requested.
The second longword of the I/O status block contains flag bits as follows:
· If bit 1 (mask value of 2) is set, there is still more data to be read before the end of the urgent data marker. This indicates that IO$_READVBLK has not read all of the urgent data.
· If bit 2 (mask value of 4) is set, the data was delivered with the urgent data marker in advance of the data. There may still be more data to be read before the end of the urgent data depending on the state of bit 1. This bit is always set if bit 1 is set.
All other bits in the second longword of the I/O status block are clear (0).
Reads the active connections status and returns status information for all of the active and listening TCPDRIVER connections.
Status = SYS$QIO(efn, chan, IO$_SENSEMODE, iosb, astadr, astprm, buffer, address, 0, 0, 0, 0);
p1 = byte *buffer
Optional address of the 8-byte device characteristics buffer. Data returned is: the device class (DC$_SCOM) in the first byte, the device type (0) in the second byte, and the default buffer size, which is the maximum datagram size, in the high-order word of the first longword. IO$_SENSEMODE returns the second longword as 0.
p2 = u_int address
Address of the descriptor for the buffer to receive the status information on the active connections.
The below diagram shows the 22 bytes of information returned for each connection.
Protocol type |
Word value is 2 for TCPDRIVER connections, 4 for INETDRIVER stream sockets, and 5 for BGDRIVER stream sockets. |
Unit number |
Word value is the TCPDRIVER, INETDRIVER, or BGDRIVER device unit number for the connection. |
Receive queue |
Word value is the number of bytes received from the peer waiting to be delivered to the user through the IO$_READVBLK function. |
Send queue |
Word value is the number of bytes waiting to be transmitted to or to be acknowledged by the peer. |
Local internet address |
Longword value is the local internet address (or 0 if the connection is not open and no local internet address was specified for the connection). |
Local port number |
Word value is the local port number. |
Peer internet address |
Longword value is the peer's internet address (or 0 if the connection is not open and no peer internet address was specified for the connection). |
Peer port number |
Word value is the peer's port number, or 0 if the connection is not open and you did not specify a peer port number for the connection. |
TCP state |
Word value is the Transmission Control Protocol connection state mask. See the IO$_SETMODE | IO$M_CTRL description for the mask value definitions. |
SS$_BUFFEROVF |
Buffer too
small for all connections |
SS$_DEVINACT |
Device not
active |
SS$_NORMAL |
Success |
The byte count for the status information buffer is returned in the high-order word of the first longword of the I/O status block. This may be less than the bytes requested. See the below figure for more information.
The size in bytes of each connection's record (22 bytes) is returned in the low order word of the second longword of the I/O status block.
The total number of active connections is returned in the high-order word of the second longword of the I/O status block. This can be greater than the number of reported connections if the buffer is full.
Reads the connection characteristics for the channel.
status = SYS$QIO(efn, chan, IO$_SENSEMODE | IO$M_CTRL, iosb, astadr, astprm, buffer, address, 0, 0, 0, 0);
p1 = byte *buffer
Optional address of the 8-byte device characteristics buffer. Data returned is: device class (DC$_SCOM) in the first byte, device type (0) in the second byte, and default buffer size (the maximum window size) in the high-order word of the first longword. IO$_SENSEMODE | IO$M_CTRL returns the second longword as 0.
p2 = u_int address
Address of the descriptor for the extended characteristics buffer to receive the characteristics. Information returned in the buffer is formatted the same as the extended characteristics buffer used to set the connection characteristics. See the IO$_SENSEMODE function for details.
If bit 12 (mask 4096) is set in the parameter identifier (PID), the PID is followed by a counted string. If bit 12 is clear, the PID is followed by a longword value. While TCPware currently never returns a counted string for a parameter, this may change in the future.
The below table shows the read connection characteristics.
PID |
Meaning |
0 |
Local internet address. Internet address is returned as the longword value. Only returned if the connection is open or a local internet address has been specified. |
1 |
Local port number. Port number is returned in the low order word of the longword value. Local port number is either the default port number or the last specified local port number. |
2 |
Peer internet address. Internet address is returned as the longword value. Only returned if the peer's internet address has been specified or the connection is open. |
3 |
Peer port number. Port number is returned in the low order word of the longword value. Only returned if the peer's port number has been specified or the connection is open. |
4 |
Connection time-out value. Time-out value (in seconds) is returned as the longword value. |
5 |
Connection window size. Window size (in bytes) is returned as the longword value. |
6 |
TCP state. State is returned as a longword bit mask value. Mask values and states are shown in the following table. Only one bit can be set at any time. |
7 |
Passive open access control. Value indicating shared (non-zero) or exclusive (zero) access to the same port number is returned as the longword value. |
10 |
Socket options. For the values of this option, see the socket options entry in Error! Reference source not found.. |
Note: The order in which IO$_SENSEMODE | IO$M_CTRL returns the parameters can change. It is recommended that you search the buffer for the desired parameter.
|
Mask Value |
State |
Mask Value |
State |
Mask Value |
State |
1 |
LISTEN |
16 |
FIN-WAIT-1 |
256 |
LAST-ACK |
2 |
SYN-SENT |
32 |
FIN-WAIT-2 |
512 |
TIME-WAIT |
4 |
SYN-RECEIVED |
64 |
CLOSE-WAIT |
1024 |
CLOSED |
8 |
ESTABLISHED |
128 |
CLOSING |
|
|
SS$_BUFFEROVF |
Buffer too
small for all characteristics |
SS$_DEVINACT |
Device not
active |
SS$_NORMAL |
Success |
The byte count for the characteristics buffer is returned in the high-order word of the first longword of the I/O status block. This may be less than the bytes requested. The number of bytes in the receive queue is returned in the low order word of the second longword in the I/O status block. The number of bytes in the read queue is returned in the high-order word of the second longword in the I/O status block. The below figure shows the I/O Status Block.
Note: You can use the SYS$GETDVI system service to obtain the local port number, peer port number, and peer internet address. The DEVDEPEND field stores the local port number (low order word) and peer port number (high-order word). The DEVDEPEND2 field stores the peer internet address.
|
Reads the TCP counters. You can add the IO$M_CLR_COUNT modifier to this function to zero the counters after they are read. However, you must have the OPER privilege to use this modifier.
status = SYS$QIO(efn, chan, IO$_SENSEMODE | IO$M_RD_COUNT, iosb, astadr, astprm, 0, address, 0, 0, 0, 0);
p2 = u_long address
Address of the descriptor for the buffer to receive the counters. These counters relate only to the TCP level and are for all connections opened since the counters were last zeroed.
The counters (longword values) in the order in which they are returned:
1. Number of seconds since last zeroed
2. Number of segments transmitted (excludes retransmissions)
3. Number of segments retransmitted (includes keep-alive check transmissions)
4. Number of segments transmitted with transmission errors
5. Number of segments received
6. Number of segments received in error (invalid TCP header or checksum)
7. Number of receive data buffers concatenated (data segments are concatenated whenever possible)
8. Number of delayed acknowledgments transmitted (included in segments transmitted count)
9. Number of window updates transmitted due to receive request completions (included in segments transmitted count)
10. Number of out-of-sequence segments received
11. Number of transmit data buffers concatenated
12. Number of keep-alives transmitted (included in number of segments re-transmitted)
SS$_BUFFEROVF |
Buffer too
small for all counters |
SS$_DEVINACT |
Device not
active |
SS$_NORMAL |
Success |
The byte count for the counters buffer is returned in the high-order word of the first longword of the I/O status block. This may be less than the bytes requested.
Requests the delivery of an attention AST whenever urgent data is available, or the connection is broken.
This function enables an attention AST to be delivered only once. The function is subject to AST quotas. After the function delivers the AST, you must issue another IO$_SETMODE | IO$M_ATTNAST to re-enable AST delivery.
When a connection fully closes, all attention ASTs for the connection are disabled.
Note: If the existence of urgent data triggers the attention AST, and that data is not read before you re-enable the AST, the AST triggers again immediately.
|
status = SYS$QIO(efn, chan, IO$_SETMODE | IO$M_ATTNAST, iosb, astadr, astprm, address, param, mode, 0, 0, 0);
p1 = void *address
Address of an AST service routine or 0 to disable attention ASTs.
p2 = u_long param
AST parameter to be passed to the AST service routine.
p3 = u_long mode
Access mode at which to deliver the AST. The access mode is maximized with the requestor's access mode.
SS$_DEVINACT |
Device not
active |
SS$_EXQUOTA |
AST quota exceeded |
SS$_NORMAL |
Success |
Sets the connection characteristics.
You specify the connection characteristics in the extended characteristics buffer. The buffer consists of a series of six-byte entries. The first word of each entry stores the parameter identifier (PID) followed by a longword that stores one of the values associated with that parameter.
status = SYS$QIO(efn, chan, IO$_SETMODE | IO$M_CTRL, iosb, astadr, astprm, 0, address, 0, 0, 0, 0);
p2 = u_int address
Address of the descriptor for the extended characteristics buffer. Counted strings consist of a word with the size of the character string followed by the character string.
The below figure shows the format of the descriptor for the extended characteristics buffer.
The below table lists the connection characteristics you can set. These characteristics remain set, even after you close the connection, until you change them with another IO$_SETMODE operation.
PID |
Meaning |
0 |
Local internet address. Longword with the local host's internet or multicast address. If used, must be a valid local internet or multicast address. Set this parameter only if the port is not open. Specify in internet byte order, reversed from the normal VMS byte order. For example, internet address 2.3.4.5 is stored as ^X05040302.
To determine if an internet address is local, issue an IO$_SETMODE | IO$M_CTRL function specifying the address in this characteristic. If the address is not local, the function returns an SS$_BADPARAM status. |
1 |
Local port number. Low order word of the longword containing the port number. If omitted, the function uses the unique port number generated when you assign the UDP device unit. Set this parameter only if the port is not open. If you use 0, the function generates a new, unique number. Specify in normal VMS byte order. |
2 |
Peer internet address. Longword with the peer host's internet address. If you specify both the peer's internet address and port number after opening the port (or when the port is opened) the port is considered fully specified (or opened as fully specified) and all further receive requests receive datagrams from that address and port only. Transmitted requests that do not provide a source/destination buffer are sent to that address and port.
Specify in internet byte order, as the local internet address characteristic above. Using 0 functionally omits the address. |
3 |
Peer port number. Low order word of the longword containing the port number. (See PID 2 above.) Specify in normal VMS byte order. Using 0 functionally omits the port number. |
4 |
Connection time-out value. Longword specifying the connection time-out value in seconds. You can also specify the connection time-out value as P6 in the IO$_SETMODE | IO$M_CTRL | IO$M_STARTUP and IO$_WRITEVBLK functions. The value specified by P6 has precedence over the value specified by the extended characteristics buffer. The default value is 5 minutes (300 seconds). The minimum is 20 seconds. |
5 |
Connection window size. Longword specifying the connection's window size (in bytes). Typical values for connection window sizes range from 4096 to 32768 and specify how much data the TCP layer will buffer for the application. If omitted, the default window size configured during network start up is used for the connection. |
7 |
Passive open access control. Specifies whether others may (shared access) or may not (exclusive access) use the same local port number in passive opens. To specify exclusive access (the default), the longword value must be 0. To specify shared access (used primarily by servers), the longword value must be non-zero. This parameter only applies to passive opens. |
9 |
Change ownership. Longword that allows the current owner of the device unit to prepare to pass ownership to another process. Removes the owner’s process ID from the connection. If the value field is non-zero, specifies the new owner UIC for the connection and changes the connection protection so that only system and owner have access (S:RWLP,O:RWLP). Changes the following fields for the connection: owner process ID, owner UIC, and device protection. Primarily the NETCP master server but also other programs use it. |
10 |
Set socket options. Low order word of the longword value field containing the mask value of the socket options to set. Specify the following options, as defined in the TCPWARE_INCLUDE:SOCKET.H header file (with values in hexadecimal):
SO_DEBUG, with a value of 0001, enables debugging (ignored) SO_REUSEADDR, with a value of 0004, allows reuse of local address (controllable through the passive open access control parameter) SO_KEEPALIVE, with a value of 0008, keeps connections alive SO_DONTROUTE, with a value of 0010, prevents routing (ignored) SO_BROADCAST, with a value of 0020, enables use of broadcasts (ignored) SO_USELOOPBACK, with a value of 0040, bypasses hardware when possible (ignored) SO_LINGER, with a value of 0080, lingers on a close |
11 |
Clear socket options. Low order word of the longword value field containing the mask of the socket options to clear. (See the options under PID 10 above.) |
12 |
No delay. Determines whether TCPDRIVER delays sending data to coalesce data from several small sends into a large packet for transmission over the network. The default is for TCPDRIVER to delay. Most applications should not change this option since the delay is very short and makes for better overall network performance. TCPDRIVER uses the parameter value passed to disable the delay (if the value is non-zero) or enable the delay (if the value is 0). |
13 |
IP options. Counted string containing the IP options to be included in datagrams. |
Note: The multicasting-related parameters (14 through 20) are supported but cannot be used with TCP (a connection-oriented protocol). Therefore, the settings are meaningless.
|
Status
SS$_BADPARAM |
Bad parameter
or value specified |
SS$_DEVACTIVE |
Connection open on unit; local port number, peer's internet address, and peer's port number cannot be changed |
SS$_DEVINACT |
Device not
active |
SS$_INSFMEM |
Insufficient memory to complete request |
SS$_IVBUFLEN |
Extended characteristics buffer length invalid |
SS$_NOPRIV |
Setting IP
layer options (PIDs 13 through 20) requires privileges |
SS$_NORMAL |
Successful
operation |
SS$_UNREACHABLE |
Default
interface for multicast group address could not be found |
Closes your end of the connection. Lets the other end of the connection know that you completed sending data. You cannot perform any IO$_WRITEVBLK functions after issuing IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN. However, you can perform IO$_READVBLK functions on the connection until the other end of the connection closes and you have read all the data.
Note: A connection does not close until it closes on both ends. In other words, your end of the connection does not close until the peer has acknowledged the IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN.
|
The recommended procedure for closing a connection is to issue IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN and then read until SS$_VCCLOSED status is returned. Use the IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN | IO$M_ABORT function to abort a connection. This function returns all requests for the connection with the SS$_VCBROKEN status. If the connection is open, it is reset.
status = SYS$QIO(efn, chan, IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN, iosb, astadr, astprm, 0, 0, 0, 0, 0, 0);
None.
SS$_DEVINACT |
Device not
active |
SS$_NORMAL |
Successful
operation |
SS$_PATHLOST |
Route to peer
lost |
SS$_THIRDPARTY |
Connection
broken by third party |
SS$_TIMEOUT |
Connection
timed-out |
SS$_VCBROKEN |
Connection broken (either locally or by source) and closed |
SS$_VCCLOSED |
Connection already closed or in process of being closed |
Opens an active connection. For an active open connection, specify the peer's internet address and port number. If you omit the local port number, the function uses a unique port number assigned when the unit was created.
Use the IO$_SETMODE | IO$M_CTRL | IO$M_STARTUP function to open a passive connection. You can omit the peer's internet address or port number. The function completes execution only after the connection is fully established.
status = SYS$QIO(efn, chan, IO$_SETMODE | IO$M_CTRL | IO$M_STARTUP, iosb, astadr, astprm, 0, address, 0, 0, 0, time);
p2 = u_int address
Address of the descriptor for the extended characteristics buffer. See the IO$_SENSEMODE | IO$M_CTRL description for details on this buffer.
p6 = u_long time
Optional connection time-out value in seconds. The default is the value specified in the extended characteristics buffer (or 5 minutes, if none was specified). The minimum value is 20 seconds.
SS$_BADPARAM |
Bad parameter or value specified |
SS$_CANCEL |
Request canceled |
SS$_DEVACTIVE |
Connection open on unit |
SS$_DUPUNIT |
Connection
not unique |
SS$_IVBUFLEN |
Buffer length invalid |
SS$_NORMAL |
Successful
operation |
SS$_NOPRIV |
Insufficient
privilege |
SS$_PATHLOST |
Route to peer
lost |
SS$_THIRDPARTY |
Connection
broken by third party |
SS$_TIMEOUT |
Connection
timed-out and closed |
SS$_VCBROKEN |
Connection
broken (either locally or by peer) and closed |
Sends data stored in the specified user buffer. Completes execution after queuing the data for transmission.
You can use the IO$M_OUTBAND modifier with IO$_WRITEVBLK to transmit urgent data.
status = SYS$QIO(efn, chan, IO$_WRITEVBLK, iosb, astadr, astprm, buffer, size, 0, 0, 0, time);
p1 = byte *buffer
Address of the user's buffer. The user's buffer stores the data to be sent.
p2 = u_int size
User's buffer size in bytes. Amount of data that the user is sending. If 0, the IO$_WRITEVBLK completes execution after transmitting all previously written data to the peer. However, the peer has not necessarily received this data yet. The value should not be greater than 64000 bytes.
p6 = u_long time
Optional new-connection timeout value (in seconds).
SS$_BADPARAM |
Bad parameter
or value specified |
SS$_DEVINACT |
Device not
active |
SS$_IVBUFLEN |
Extended characteristics buffer length invalid |
SS$_NORMAL |
Successful
operation |
SS$_PATHLOST |
Route to peer
lost |
SS$_THIRDPARTY |
Connection
broken by third party |
SS$_TIMEOUT |
Connection
timed-out and fully closed |
SS$_VCBROKEN |
Connection broken (either locally or by source) and fully closed |
SS$_VCCLOSED |
You issued close function to close end of connection, or connection never opened |
The number of bytes sent is returned in the high-order word of the first longword of the I/O status block.
Sends data stored in a list of buffers.
status = SYS$QIO(efn, chan, IO$_WRITEVBLK | IO$M_EXTEND, iosb, astadr, astprm, msghdr, size, 0, 0, 0, 0);
p1 = u_long *msghdr
Address of the msghdr structure. Points to the address of the structure storing the array of additional structures. Each of these array structures contains the address and size of one of the user buffers. The msghdr structure is as follows:
struct msghdr {
char *msg_name; /*optional address*/
int msg_namelen; /*size of address*/
struct iovec *msg_iov; /*scatter/gather array*/
int msg_iovlen; /*elements in msg_iov*/
char *msg_accrights; /*access rights*/
int msg_accrightslen;
};
struct iovec {
char *iov_base; /*address of buffer*/
int iov_len; /*length of buffer*/
};
In the msghdr structure, this function uses only msg_iov and msg_iovlen. It ignores the values of the other elements.
msg_iov stores the address of the array of iovec structures and msg_iovlen is the number of iovec elements in the array. The iovec array stores the address and length of each buffer (in bytes) that holds the data to be sent.
p2 = u_long size
Size of the msghdr structure, which must be 24 bytes. The following is an example using the scatter-gather write function. The below figure shows a diagram for the example.
struct msghdr buflst;
struct iovec bufiov[3];
char buffer1[100];
char buffer2[20];
char buffer3[200];
buflst.msg_iov = bufiov;
buflst.msg_iovlen = 3;
bufiov[0].iov_base = buffer1;
bufiov[0].iov_len = sizeof(buffer1)
bufiov[1].iov_base = buffer2;
bufiov[1].iov_len = sizeof(buffer2)
bufiov[2].iov_base = buffer3;
bufiov[2].iov_len = sizeof(buffer13)
istat = SYS$QIOW(0,chan,
IO$_WRITEVBLK | IO$M_EXTEND,&iosb,0,0,buflst,sizeof(buflst),
0,0,0);
See IO$_WRITEVBLK
Assigns a channel to a device.
status = SYS$ASSIGN(char *devnam, u_int *chan, [u_long acmode], [char *mbxnam]);
devnam
Address of a character string descriptor pointing to the device name string (TCP0:).
chan
Address of a word into which SYS$ASSIGN writes the channel number.
acmode
Optional access mode associated with the channel. The most privileged access mode used is that of the caller.
mbxnam
Optional logical mailbox associated with the device. (Not supported by TCPDRIVER.)
See the VMS System Services Reference Manual for a complete list of status messages.
Cancels any I/O that is pending on a socket. The I/O will be completed with an iosb status of SS$_CANCEL.
Outstanding I/O operations are automatically cancelled at image exit.
status = SYS$CANCEL(u_int chan);
chan
Number of the channel to be canceled.
See HP’s VMS System Services Reference Manual for a complete list of status messages.
Releases a channel.
When you deassign a channel, any outstanding I/O is completed with an iosb status of SS$_CANCEL. If a connection is open on the channel, it is aborted.
I/O channels are automatically deassigned at image exit.
status = SYS$DASSGN(u_int chan);
chan
Number of the channel to be deassigned.
See the VMS System Services Reference Manual for a complete list of status messages.
The following sample programs are included in the TCPWARE_COMMON:[TCPWARE.EXAMPLES] directory:
· TCPDRIVER_CLIENT.C
· TCPDRIVER_SERVER.C
· FINGER.C
The first two pairs of programs show the use of stream sockets with SYS$QIO system service calls to the TCPDRIVER. They are functionally the same as the TCP_SOCKET_CLIENT.C and TCP_SOCKET_SERVER.C socket library programs.
The client sequence of operations is as follows:
1. Assigns an I/O channel to TCP0, using SYS$ASSIGN.
2. Opens a connection, using (IO$_SETMODE | IO$M_CTRL | IO$M_STARTUP).
3. Exchanges data, using IO$_WRITEVBLK and IO$_READVBLK.
4. Closes the connection, using (IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN).
5. Performs additional reads until the peer returns an SS$_VCCLOSED status.
6. Deassigns the channel, using SYS$DASSGN.
The server sequence of operations is as follows:
1. Assigns an I/O channel to TCP0, using SYS$ASSIGN.
2. Causes
a passive open of the connection, using (IO$_SETMODE |
IO$M_CTRL | IO$M_STARTUP | 0x0800). You can alternately use TCPDRIVER's IO$_CREATE function that listens and accepts connections
with UNIX-like functionality (use the
/DEFINE=USE_CREATE command in the CC line
of the build process).
3. Exchanges data, using IO$_WRITEVBLK and IO$_READVBLK.
4. Closes the connection, using (IO$_SETMODE | IO$M_CTRL | IO$M_SHUTDOWN).
5. Deassigns the channel, using SYS$DASSGN.
The FINGER.C file for the FINGER protocol also contains sample source code using TCPDRIVER services.
Link the files to the TCPware Socket Library as follows for Alpha, VAX, and Itanium systems for DEC C:
$ LINK FINGER
SYS$INPUT/OPTIONS SYS$SHARE:TCPWARE_SOCKLIB_SHR/SHARE
$ Ctrl+Z
To build on a VAX with VAX C:
$ CC FINGER.C
$ LINK FINGER,SYS$INPUT/OPTIONS
TCPWARE:UCX$IPC.OLB/LIBRARY -
_$ SYS$SHARE:VAXCRTL/SHARE
$ Ctrl+Z
$ FINGER :== $device:[directory]FINGER
To build on an Alpha, VAX, or Itanium systems with DEC C:
$ CC/PREFIX=ALL FINGER.C
$ LINK FINGER
$ FINGER :== $device:[directory]FINGER
Then type:
$ FINGER username@host
or
$ FINGER @host
To build on a VAX with VAX C:
$ CC
FINGERD.C
$ LINK FINGERD,SYS$INPUT/OPTIONS
TCPWARE:UCX$IPC.OLB/LIBRARY -
_$ SYS$SHARE:VAXCRTL.EXE/SHARE
To build on an Alpha,VAX, or Itanium system with DEC C:
$ CC/PREFIX=ALL
FINGERD.C
$ LINK FINGERD,SYS$INPUT/OPTIONS SYS$SHARE:TCPWARE_SOCKLIB_SHR/SHARE
Use the NETCU ADD SERVICE and (optionally) the ADD ACCESS commands to "start" the server. The ADD ACCESS commands can be used to restrict access to the FINGER server to specific hosts or networks. For example:
$ NETCU ADD
SERVICE FINGER TCP path:FINGERD -
_$ /PRIV=(NOSAME,NETMBX,TMPMBX,WORLD,SYSPRV) /ACCESS=n
Add these commands to the TCPWARE:SERVERS.COM file so that the server starts whenever TCPware starts.
The TCPWARE_COMMON:[TCPWARE.EXAMPLES] directory also includes a TCPSAMPLE.FOR FORTRAN language file that transmits or receives data. This program links to the TCPware Socket Library as follows:
$ FORTRAN/NOALIGN
TCPWARE_COMMON:[TCPWARE.EXAMPLES]TCPSAMPLE
$ LINK TCPSAMPLE, SYS$INPUT/OPTIONS
SYS$SHARE:TCPWARE_SOCKLIB_SHR/SHARE
Ctrl+Z
$ FORTRAN
TCPWARE_COMMON:[TCPWARE.EXAMPLES]TCPSAMPLE
$ LINK TCPSAMPLE, SYS$INPUT/OPTIONS
SYS$SHARE:TCPWARE_SOCKLIB_SHR/SHARE
Ctrl+Z