[an error occurred while processing this directive]

HP OpenVMS Systems Documentation

Content starts here

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


Previous Contents Index

1.3.2 Libraries

Table 1-3 lists the function libraries included with TCP/IP Services.

Table 1-3 Sockets API Libraries
File Location Description
TCPIP$IPC_SHR.EXE SYS$LIBRARY Sockets API Run-Time Library
TCPIP$LIB.OLB TCPIP$LIBRARY BSD Version 4.4 Sockets object library

1.3.3 Programming Examples

Table 1-4 and Table 1-5 summarize the programming examples included with TCP/IP Services in the TCPIP$EXAMPLES directory. Most of these examples consist of a client and a corresponding server.






Table 1-4 TCP Programming Examples
File Description
TCPIP$TCP_SERVER_SOCK.C
TCPIP$TCP_CLIENT_SOCK.C
Example TCP client and server using the Sockets API.
TCPIP$TCP_SERVER_SOCK_AUXS.C Example TCP server using the Sockets API that accepts connections from the auxiliary server.
TCPIP$TCP_SERVER_QIO.C
TCPIP$TCP_CLIENT_QIO.C
Example TCP client and server using QIO system services.
TCPIP$TCP_SERVER_QIO_AUXS.C Example TCP server using QIO system services that accepts connections from the auxiliary server.
TCPIP$TCP_CLIENT_QIO.MAR
TCPIP$TCP_SERVER_QIO.MAR
Example TCP client and server using QIO system services and the MACRO-32 programming language.



Table 1-5 UDP Programming Examples
File Description
TCPIP$UDP_SERVER_SOCK.C
TCPIP$UDP_CLIENT_SOCK.C
Example UDP client and server using the Sockets API.
TCPIP$UDP_SERVER_QIO.C
TCPIP$UDP_CLIENT_QIO.C
Example UDP client and server using QIO system services.
TCPIP$UDP_CLIENT_QIO.MAR
TCPIP$UDP_SERVER_QIO.MAR
Example UDP client and server using QIO system services and the MACRO-32 programming language.

1.4 Compiling and Linking C Language Programs

To compile and link a C program called MAIN.C, enter the following commands:


$ CC MAIN.C
$ LINK MAIN.OBJ

1.4.1 Compiling and Linking Programs Using BSD Version 4.4

To compile and link MAIN.C using BSD Version 4.4, enter the following commands:


$ CC/DEFINE=(_SOCKADDR_LEN) MAIN.C

$ LINK MAIN.OBJ

Instead of using the /DEFINE=(_SOCKADDR_LEN) option to the compile command, you can change your code to include the following #DEFINE preprocessor directive:


#define   _SOCKADDR_LEN    1

This statement must appear before you include any of the following header files:


#include <in.h>
#include <netdb.h>
#include <inet.h>

1.4.2 C Compilation Warnings

Certain parameters to the TCP/IP Services Sockets API functions require typecasting to avoid C compilation warnings. Typecasting is required because of parameter prototyping, which the C header (filename.H) files have in order to comply with ANSI standards.

1.5 Using 64-Bit Addresses (Alpha and I64 Only)

For applications that run on OpenVMS Alpha and I64 systems, input and output (I/O) operations can be performed directly to and from the P2 or S2 addressable space by means of the 64-bit friendly $QIO and $QIOW system services.

To write data to a remote host, use the $QIO(IO$_WRITEVBLK) function with either the p1 (input buffer) or p5 (input buffer list) parameter. The address you specify for the parameter can be a 64-bit value.

To read data from a remote host, use the $QIO(IO$_READVBLK) function with either the p1 (output buffer) or p6 (output buffer list) parameter. The address you specify for the parameter can be a 64-bit value.

MACRO-32 does not provide 64-bit macros for system services. For more information about MACRO-32 programming support and for 64-bit addressing in general, see the OpenVMS Alpha Guide to 64-Bit Addressing and VLM Features.

For more information about using the $QIO and $QIOW system services for 64-bit addressing, see Chapter 5 and Chapter 6.


Chapter 2
Writing Network Applications

You can use either the Sockets API or OpenVMS system services to write TCP/IP applications that run on your corporate network. These applications consist of a series of system calls that perform tasks, such as creating a socket, performing host and IP address lookups, accepting and closing connections, and setting socket options. These system calls are direct entry points that client and server processes use to obtain services from the TCP/IP kernel software. System calls look and behave exactly like other procedural calls in that they take arguments and return one or more results, including a status value. These arguments can contain values or pointers to objects in the application program.

This chapter describes the communication process followed by client and server applications. This process reflects the sequence of system calls within the client and server programs (see Tables 2-1 through 2-4). The chapter also includes Sockets API and OpenVMS system services examples for each step in the communication process.

2.1 The Client/Server Communication Process

The most commonly used paradigm in constructing distributed applications is the client/server model. The requester, known as the client, sends a request to a server and waits for a response. The server is an application-level program that offers a service that can be reached over the network. Servers accept requests that arrive over the network, perform their service, and return the result to the client.

A network connection also has a mode of communication: either connection-oriented or connectionless. When writing network applications, the developer uses the mode of communication required by the application-level service. If the application-level service uses the connection-oriented mode of communication, the developer uses the Transmission Control Protocol (TCP). If the application-level service uses the connectionless mode of communication, then the developer uses the the User Datagram Protocol (UDP). The following sections describe how to use TCP and UDP.

2.1.1 Using the TCP Protocol

Figure 2-1 shows the communication process for a TCP client/server application.

Figure 2-1 Client/Server Communication Process Using TCP


In this figure:

  1. Server issues a call to create a listening socket.
  2. Server and client create a socket.
  3. Server and client bind socket. (This step is optional for a client.)
  4. Server converts an unconnected socket into a passive socket (LISTEN state).
  5. Server issues an accept() and process blocks waiting for a connection request.
  6. Client sends a connection request.
  7. Server accepts the connection; a new socket is created for communication with this client.
  8. Server receives device information from the local host.
  9. Data exchange takes place.
  10. Client and server delete the socket.
  11. Server deletes the listener socket when the service to the client is terminated.

For server applications that use the TCP protocol, Table 2-1 identifies the typical communication tasks, the applicable Sockets API function, and the equivalent OpenVMS system service.

Table 2-1 TCP Server Tasks and Related Functions
Task Sockets API Function OpenVMS System Services
Create a socket socket() $ASSIGN
$QIO(IO$_SETMODE) 1
Bind socket name bind() $QIO(IO$_SETMODE) 1
Define listener socket listen() $QIO(IO$_SETMODE) 1
Accept connection request accept() $QIO(IO$_ACCESS|IO$M_ACCEPT)
Exchange data read()
recv()
recvmsg()
$QIO(IO$_READVBLK)
  write()
send()
sendmsg()
$QIO(IO$_WRITEVBLK)
Shut down the socket (optional) shutdown() $QIO(IO$_DEACCESS|IO$M_SHUTDOWN)
Close and delete the socket close() $QIO(IO$_DEACCESS)
$DASSGN

1The $QIO system service calls for creating a socket, binding a socket name, and defining a network pseudodevice as a listener are listed as three separate calls in this table. You can perform all three steps with one $QIO(IO$_SETMODE) call.

For a client application using the TCP protocol, Table 2-2 shows the tasks in the communication process, the applicable Sockets API functions, and the equivalent OpenVMS system services.

Table 2-2 TCP Client Tasks and Related Functions
Task Sockets API Function OpenVMS System Services
Create a socket socket() $ASSIGN
$QIO(IO$_SETMODE) 1
Bind socket name bind() $QIO(IO$_SETMODE) 1
Connect to server connect() $QIO(IO$_ACCESS)
Exchange data read()
recv()
recvmsg()
$QIO(IO$_READVBLK)
  write()
send()
sendmsg()
$QIO(IO$_WRITEVBLK)
Shut down the socket (optional) shutdown() $QIO(IO$_DEACCESS|IO$M_SHUTDOWN)
Close and delete the socket close() $QIO(IO$_DEACCESS)
$DASSGN

1The $QIO system service calls for creating a socket and binding a socket name are listed as two separate calls in this table. You can perform both steps with one $QIO(IO$_SETMODE) call.

2.1.2 Using the UDP Protocol

Figure 2-2 shows the steps in the communication process for a client/server application using the UDP protocol.

Figure 2-2 UDP Socket Communication Process


In this figure:

  1. Server and client create a socket.
  2. Server and client bind the socket name. (This step is optional for a client.)
  3. Data exchange takes place.
  4. Server and client delete the socket.

For server applications using the UDP protocol, Table 2-3 identifies the tasks in the communication process, the Sockets API functions, and the equivalent OpenVMS system services.

Table 2-3 UDP Server Tasks and Related Functions
Task Sockets API Function OpenVMS System Service
Create a socket socket() $ASSIGN
$QIO(IO$_SETMODE) 1
Bind socket name bind() $QIO(IO$_SETMODE) 1
Exchange data read()
recv()
recvfrom()
recvmsg()
$QIO(IO$_READVBLK)
  write()
send()
sendto()
sendmsg()
$QIO(IO$_WRITEVBLK)
Shut down the socket (optional) shutdown() $QIO(IO$_DEACCESS|IO$M_SHUTDOWN)
Close and delete the socket close() $QIO(IO$_DEACCESS)
$DASSGN

1The $QIO system service calls for creating a socket and binding a socket name are listed as two separate calls in this table. You can perform both steps with one $QIO(IO$_SETMODE) call.

For client applications using the UDP protocol, Table 2-4 describes the tasks in the communication process, the Sockets API function, and the equivalent OpenVMS system service.

Table 2-4 UDP Client Tasks and Related Functions
Task Sockets API Function OpenVMS System Service
Create a socket socket() $ASSIGN
$QIO(IO$_SETMODE) 1
Bind socket name (optional) bind() $QIO(IO$_SETMODE) 1
Specify a destination address for outgoing datagrams connect() $QIO(IO$_ACCESS)
Exchange data read()
recv()
recvfrom()
recvmsg()
$QIO(IO$_READVBLK)
  write()
send()
sendto()
sendmsg()
$QIO(IO$_WRITEVBLK)
Shut down the socket (optional) shutdown() $QIO(IO$_DEACCESS|keep>(IO$M_SHUTDOWN))
Close and delete the socket close() $QIO(IO$_DEACCESS)
$DASSGN

1The $QIO system service calls for creating a socket and binding a socket name are listed as two separate calls in this table. You can perform both of these steps with one $QIO(IO$_SETMODE) call.

2.2 Creating a Socket

For network communication to take place between two processes, each process requires an end point to establish a communication link between the two processes. This end point, called a socket, sends messages to and receives messages from the socket associated with the process at the other end of the communication link.

Sockets are created by issuing a call to the socket() Sockets API function or by the $ASSIGN and $QIO(IO$_SETMODE) system service, specifying an address family, a protocol family, and a socket type.

If the socket creation is successful, the operation returns a small positive integer value called a socket descriptor, or sockfd. From this point on, the application program uses the socket descriptor to reference the newly created socket.

In the TCP/IP Services implementation, this socket is also referred to as a device socket. A device socket is the pairing of an OpenVMS network device and a BSD-style socket. A device socket is either implicitly created by the Sockets API, or explicitly created using OpenVMS system services. The socket() function calls the $QIO system services to create the socket.

For information about creating a socket using the Sockets API, see Section 2.2.1. For information about explicitly creating a device socket, see Section 2.2.2.

To display information about a device socket, use the TCP/IP management command SHOW DEVICE_SOCKET.

TCP/IP operations are performed as I/O functions of the network device. The logical name for the network device is TCPIP$DEVICE.

2.2.1 Creating Sockets (Sockets API)

When using the Sockets API, create the socket with a call to the socket() function. Example 2-1 shows how to create a TCP socket using the Sockets API.

Example 2-1 Creating 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    */

int main( void )
{
    int sockfd;

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

    exit( EXIT_SUCCESS );
}

This example shows how to use the socket() function to create a socket.

  1. This line creates the socket with the following arguments:
    • AF_INET specifies the IPv4 address family.
    • SOCK_STREAM specifies that the socket type is stream (TCP).
    • 0 specifies that the protocol type is IPPROTO_TCP (default).

2.2.2 Creating Sockets (System Services)

When you use OpenVMS system services, you make two calls to create the socket:

  • $ASSIGN to assign a channel to the network device
  • $QIO or $QIOW to create the socket
    The Queue I/O Request ($QIO) service completes asynchronously. It returns to the caller immediately after queuing the I/O request, without waiting for the I/O operation to complete.
    For synchronous completion, use the Queue I/O Request and Wait ($QIOW) service. The $QIOW service is identical to the $QIO service, except the $QIOW returns to the caller after the I/O operation completes.

When you make the $QIO or $QIOW call, use either the IO$_SETMODE or the IO$_SETCHAR I/O service. You generally create, bind, and set up sockets to listen with one $QIO call. For network software, the IO$_SETMODE and IO$_SETCHAR services perform in an identical manner. However, you must have LOG_IO privilege to successfully use the IO$_SETMODE I/O service modifier.

When a channel is assigned to the TCPIP$DEVICE template network device, TCP/IP Services creates a new pseudodevice with a unique unit number and returns a channel number to use in subsequent operation requests with that device.

When the auxiliary server creates your application server process in response to incoming network traffic for a service with the LISTEN flag, it creates a device socket for your application server process. For your application to receive the device socket, assign a channel to SYS$NET (the logical name of a network pseudodevice) and perform an appropriate $QIO(IO$_SETMODE) function. For a discussion of the auxiliary server, see the HP TCP/IP Services for OpenVMS Management manual.

Example 2-2 shows how to create a TCP socket using OpenVMS system services.

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

    /*
     * initialize socket characteristics
     */
(2)
    sockchar.prot = TCPIP$C_TCP;
    sockchar.type = TCPIP$C_STREAM;
    sockchar.af   = TCPIP$C_AF_INET;

    /*
     * assign i/o channel to network device
     */
(3)
    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
     */
(4)
    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 );
        }

    exit( EXIT_SUCCESS );
}


Previous Next Contents Index