HP OpenVMS Systems Documentation

Content starts here

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


Previous Contents Index


Chapter 3
Using the Sockets API

This chapter describes how to use the Sockets API functions.

3.1 Internet Protocols

The IP (Internet Protocol) family is a collection of protocols on the Transport layer that use the Internet address format. The two basic Internet protocols are:

  • TCP (Transmission Control Protocol)
  • UDP (User Datagram Protocol)

The TCP/IP protocol suite has been extended beyond the basic 32-bit addressing capabilities of IPv4. With the new IPv6 protocol, the address size is increased to 128 bits. The basic syntax of socket functions remains the same, with extensions to the basic sockets API and advanced sockets application programming interfaces.

The following sections describe the basic TCP and UDP protocols, including the extensions provided for IPv6.

3.1.1 TCP Sockets

TCP provides reliable, flow-controlled, two-way transmission of data. A byte-stream protocol used to support the SOCK_STREAM abstraction, TCP uses standard IP address formats and provides a per-host collection of port addresses. Thus, each address consists of an internet address specifying the host and network, with a specific TCP port on the host identifying the peer entity.

Sockets using TCP are either active or passive, as described in Table 3-1.

Table 3-1 TCP Socket Types
Socket Type Description
Active Initiates connections to passive sockets. By default, TCP sockets are active.

Active sockets use the connect() function to initiate connections.

Passive Listens for connection requests from active sockets. To create a passive socket, use the bind() function and then the listen() function.

Passive sockets use the accept() function to accept incoming connections.

If the server is running on a multihomed system, you can specify wildcard addressing. Wildcard addressing allows a single server to provide service to clients on multiple networks. (See Section 3.1.1.1.)

3.1.1.1 Wildcard Addressing

When a server is running on a host that has more than one network interface installed, you can use wildcard addressing to configure it to accept incoming connections on all the interfaces.

The wildcard address is the any-interface choice. You specify this address by setting the IP address in the socket address structure to INADDR_ANY (for IPv4) or in6addr_any (for IPv6) before calling the bind() function.

To create a socket that listens to all hosts on any network interface, perform these steps:

  1. Bind the IP address ( INADDR_ANY or in6addr_any ). See Section 2.3.
  2. Specify the TCP port.
    If you do not specify the port, the system assigns a unique port, starting at port number 49152. Once connected, the socket's address is fixed by the peer entity's location.

The address assigned to the socket is the address associated with the network interface through which packets from the peer are being transmitted and received. This address corresponds to the peer entity's network.

TCP supports the setting of socket options with the setsockopt() function and the checking of current option settings with the getsockopt() function. Under most circumstances, TCP sends data when it is presented. When outstanding data has not been acknowledged, TCP gathers small amounts of output and sends it in a single packet when an acknowledgment is received.

Note

For some clients, such as Microsoft Windows systems, which send a stream of mouse events that receive no replies, this packetization can cause significant delays. TCP/IP Services provides the TCP_NODELAY option (defined in the TCP.H header file) to manage this problem. Refer to Table A-2 for more information about setting this option. Note that this solution may cause an increase in network traffic.

3.1.2 UDP Sockets

UDP is a protocol that supports the SOCK_DGRAM abstraction for the internet protocol family. UDP sockets are connectionless and are normally used with the sendto() and recvfrom() functions. You can also use the connect() function to establish the destination address for future datagrams; then you use the read() , write() , send() , or recv() function to transmit or receive datagrams.

UDP address formats are identical to those used by TCP. In particular, UDP provides a port identifier in addition to the normal internet address format. Note that the UDP port space is separate from the TCP port space (for example, a UDP port cannot be connected to a TCP port). Also, you can send broadcast packets (assuming the underlying network supports broadcasting) by using a reserved broadcast address. This address is network-interface dependent. The SO_BROADCAST option must be set on the socket, and the process must have SYSPRV, BYPASS, or OPER privilege for broadcasting to succeed.

3.2 Structures

This section describes, in alphabetical order, the structures you supply as arguments to the various Sockets API functions. Table 3-2 lists these structures.

Table 3-2 Structures for Sockets API
Structure Description
addrinfo This structure describes the type of socket, the address family, and the protocol.
cmsghdr This structure describes ancillary data objects transferred by the sendmsg() and recvmsg() functions.
hostent This structure holds a canonical host name, alias names, a host address type, the length of the address, and a pointer to a list of host addresses. This structure is a parameter value for host name and address lookup functions.
in_addr This structure holds a 32-bit IPv4 address stored in network byte order.
in6_addr This structure holds a 128-bit IPv6 address stored in network byte order as an array of sixteen 8-bit elements.
iovec This structure holds the beginning address and length of an I/O buffer.
linger This structure holds option information for the close function.
msghdr This structure holds the protocol address, the size of the protocol address, a scatter-and-gather array, the number of elements in the scatter-and-gather array, ancillary data, the length of the ancillary data, and returned flags. The structure is a parameter of the recvmsg() and sendmsg() functions.
netent This structure holds a network name, a list of aliases associated with the network, and the network number.
protoent This structure describes a protocol.
servent This structure describes a network service.
sockaddr The socket functions use this generic socket address structure to function with any of the supported protocol families.
sockaddr_in This IPv4 socket address structure holds the length of the structure, the address family, either a TCP or a UDP port number, and a 32-bit IPv4 address stored in network byte order. The structure has a fixed length of 16 bytes.
sockaddr_in6 This IPv6 socket address structure holds the length of the structure, the address family, the transport layer port number, a priority and flow label, and a 128-bit IPv6 address. The structure has a fixed length of 28 bytes.
timeval This structure holds a time interval specified in seconds and microseconds.

3.2.1 addrinfo Structure

The addrinfo structure is defined in the NETDB.H header file, and consists of the following components:


struct addrinfo {
        int              ai_flags;      /* input flags                     */
        int              ai_family;     /* protofamily for socket          */
        int              ai_socktype;   /* socket type                     */
        int              ai_protocol;   /* protocol for socket             */
        size_t           ai_addrlen;    /* length of socket-address        */
        char            *ai_canonname;  /* service location canonical name */
        struct sockaddr *ai_addr;       /* socket-address for socket       */
        struct addrinfo *ai_next;       /* pointer to next in list         */
};

3.2.2 cmsghdr Structure

The cmsghdr structure describes ancillary data objects transferred by the sendmsg and recvmsg functions.

The msg_control member of the msghdr data structure points to the ancillary data that are contained in a cmsghdr structure. Typically, only one data object is passed in a cmsghdr structure. However, the IPv6 advanced sockets API enables the sendmsg and recvmsg functions to pass multiple objects. For information about using raw IPv6 sockets, see Section 3.6.1.

The data structure is defined in the SOCKET.H header file.

The cmsghdr data structure consists of the following components


struct cmsghdr {
        socklen_t cmsg_len;     /* #bytes, including this header */
        int cmsg_level;         /* originating protocol          */
        int cmsg_type;          /* protocol-specific type        */
        /* followed by unsigned char cmsg_data[];                */
};

3.2.3 hostent Structure

The hostent structure, defined in the NETDB.H header file, holds a host name, a list of aliases associated with the network, and the network's number as specified in an internet address from the hosts database.

The hostent structure definition is as follows:



struct  hostent {
        char    *h_name;        /* official name of host               */
        char    **h_aliases;    /* alias list                          */
        int     h_addrtype;     /* host address type                   */
        int     h_length;       /* length of address                   */
        char    **h_addr_list;  /* list of addresses from name server  */
};
#define h_addr  h_addr_list[0]  /* address, for backward compatibility */

The hostent structure members are as follows:

  • h_name is a pointer to a null-terminated character string that is the official (canonical) name of the host.
  • h_aliases is a pointer to an array of pointers to alias names for the host.
  • h_addrtype is the type of host address being returned (AF_INET or AF_INET6).
  • h_length is the length, in bytes, of the address. (For IPv4, this value is 4 bytes.)
  • h_addr_list is a pointer to an array of pointers to the network addresses for the host. Each host address is represented by a series of bytes in network order. The list is terminated with a null pointer value.
  • h_addr is the first address in the h_addr_list .

3.2.4 in_addr Structure

The in_addr structure, defined in the IN.H header file, holds an IPv4 address. The address format can be any of the supported internet address notation formats.

The in_addr structure definition is as follows:



struct in_addr {
       union {
                struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;
                struct { u_short s_w1,s_w2; } S_un_w;
                u_long S_addr;
}      S_un;
#define s_addr  S_un.S_addr             /* can be used for most tcp & ip code */
#define s_host  S_un.S_un_b.s_b2        /* host on imp                        */
#define s_net   S_un.S_un_b.s_b1        /* network                            */
#define s_imp   S_un.S_un_w.s_w2        /* imp                                */
#define s_impno S_un.S_un_b.s_b4        /* imp #                              */
#define s_lh    S_un.S_un_b.s_b3        /* logical host                       */
};

3.2.5 in6_addr Structure (IPv6)

The in6_addr structure, defined in the IN6.H header file, holds an IPv6 address. The address format can be any of the supported internet address notation formats. The address is stored in network byte order as an array of sixteen 8-bit elements.

The in6_addr structure definition is as follows:


     struct in6_addr {
          u_int8_t s6_addr[16]
     }

A wildcard address, defined in network byte order, has the following forms:

  • A global variable, in6addr_any , that is an in6_addr structure.
  • A symbolic constant, IN6ADDR_ANY_INIT, that can be used to initialize an in6_addr structure only when it is declared.

A loopback address, defined in network byte order, has the following forms:

  • A global variable, in6addr_loopback , that is an in6_addr structure.
  • A symbolic constant, IN6ADDR_LOOPBACK_INIT, that can be used to initialize an in6_addr structure only when it is declared.

3.2.6 iovec Structure

The iovec structure holds one scatter-and-gather buffer. Multiple scatter-and-gather buffer descriptors are stored as an array of iovec elements.

The iovec structure definition is defined in the SOCKET.H header file.

The iovec structure definition is as follows:



struct iovec {
       char *iov_base;
       int  iov_len;
}

The iovec structure members are as follows:

  • iov_base is a pointer to a buffer.
  • iov_len contains the size of the buffer to which iov_base points.

3.2.7 linger Structure

The linger structure, defined in the SOCKET.H header file, specifies the setting or resetting of the socket option for the time interval that the socket lingers for data. The linger structure is supported only by connection-based (SOCK_STREAM) sockets.

The linger structure definition is as follows:



struct  linger {
        int     l_onoff;                 /* option on/off  */
        int     l_linger;                /* linger time    */
};

The linger structure members are as follows:

  • l_onoff =1 sets linger ; l_onoff =0 resets linger .
  • l_linger is the number of seconds to linger. (The default is 120 seconds, or 2 minutes.)

3.2.8 msghdr Structure

The msghdr structure specifies the buffer parameter for the recvmsg and sendmsg I/O functions. The structure allows you to specify an array of scatter and gather buffers. The recvmsg function scatters the data to several user receive buffers, and the sendmsg function gathers data from several user transmit buffers before being transmitted.

The SOCKET.H header file defines the following structures for BSD Versions 4.3 and 4.4:

  • omsghdr structure (BSD Version 4.3)
  • msghdr structure (32- and 64-bit) (BSD Version 4.4)

3.2.8.1 BSD Version 4.3

The omsghdr structure definition for use with BSD Version 4.3 is as follows:



struct omsghdr {
       char          *msg_name;         /* protocol address               */
       int           msg_namelen;       /* size of address                */
       struct iovec  *msg_iov;          /* scatter/gather array           */
       int           msg_iovlen;        /* number of elements in msg_iov  */
       char          *msg_accrights;    /* access rights sent/received    */
       int           msg_accrightslen;  /* length of access rights buffer */
};

The omsghdr structure members are as follows:

  • msg_name is the address of the destination socket if the socket is not connected. If no address is required, you can set this field to null.
  • msg_namelen is the length of the msg_name field.
  • msg_iov is an array of I/O buffer pointers of the iovec structure form. See Section 3.2.6 for a description of the iovec structure.
  • msg_iovlen is the number of buffers in the msg_iov array.
  • msg_accrights points to a buffer containing access rights sent with the message.
  • msg_accrightslen is the length of the msg_accrights buffer.

3.2.8.2 BSD Version 4.4

The msghdr structure definition for use with BSD Version 4.4 is as follows:



struct msghdr {
       void         *msg_name;       /* protocol address                */
       int          msg_namelen;     /* size of address                 */
       struct iovec *msg_iov;        /* scatter/gather array            */
       int          msg_iovlen;      /* number of elements in msg_iov   */
       void         *msg_control;    /* ancillary data; must be aligned
                                        for a cmsghdr structure         */
       int          msg_controllen;  /* length of ancillary data buffer */
       int          msg_flags;       /* flags on received message       */
};

The msghdr structure members are as follows:

  • msg_name is the address of the destination socket if the socket is not connected. If no address is required, you can set this field to null.
  • msg_namelen is the length of the msg_name field.
  • msg_iov is an array of I/O buffer pointers of the iovec structure form. See Section 3.2.6 for a description of the iovec structure.
  • msg_iovlen is the number of buffers in the msg_iov array.
  • msg_control specifies the location of the optional ancillary data or control information.
  • msg_controllen is the size of the ancillary data in the msg_control buffer.
  • msg_flags , used only with the recvmsg function, is the value used by the kernel to drive its receive processing.


Previous Next Contents Index