Using AF_UNIX address family
Sockets that use the AF_UNIX or AF_UNIX_CCSID address family can be connection-oriented (type SOCK_STREAM) or connectionless (type SOCK_DGRAM).
Both types are reliable because there are no external communication functions connecting the two processes.
UNIX domain datagram sockets act differently from UDP datagram sockets. With UDP datagram sockets, the client program does not need to call the bind() API because the system assigns an unused port number automatically. The server can then send a datagram back to that port number. However, with UNIX domain datagram sockets, the system does not automatically assign a path name for the client. Thus, all client programs using UNIX domain datagrams must call the bind() API. The exact path name specified on the client's bind() is what is passed to the server. Thus, if the client specifies a relative path name (that is, a path name that is not fully qualified by starting with /), the server cannot send the client a datagram unless it is running with the same current directory.
The following figure illustrates the client/server relationship of the AF_UNIX address family.
![Socket flow of events used in server and client AF_UNIX address family example programs.](rzab6503.gif)
Socket flow of events: Server application that uses AF_UNIX address family
The first example uses the following sequence of API calls:
- The socket() API returns a socket descriptor,
which represents an endpoint. The statement also identifies the UNIX address family
with the stream transport (SOCK_STREAM) being used for this socket. You can
also use the socketpair() API to initialize a UNIX socket.
AF_UNIX or AF_UNIX_CCSID are the only address families to support the socketpair() API. The socketpair() API returns two socket descriptors that are unnamed and connected.
- After the socket descriptor is created, the bind() API
gets a unique name for the socket.
The name space for UNIX domain sockets consists of path names. When a sockets program calls the bind() API, an entry is created in the file system directory. If the path name already exists, the bind() fails. Thus, a UNIX domain socket program should always call an unlink() API to remove the directory entry when it ends.
- The listen() allows the server to accept incoming client connections. In this example, the backlog is set to 10. This means that the system queues 10 incoming connection requests before the system starts rejecting the incoming requests.
- The recv() API receives data from the client application. In this example, the client sends 250 bytes of data over. Thus, the SO_RCVLOWAT socket option can be used, which specifies that recv() is not required to wake up until all 250 bytes of data have arrived.
- The send() API echoes the data back to the client.
- The close() API closes any open socket descriptors.
- The unlink() API removes the UNIX path name from the file system.
Socket flow of events: Client application that uses AF_UNIX address family
The second example uses the following sequence of API calls:
- The socket() API returns a socket descriptor,
which represents an endpoint. The statement also identifies the UNIX address family
with the stream transport (SOCK_STREAM) being used for this socket. You can
also use the socketpair() API to initialize a UNIX socket.
AF_UNIX or AF_UNIX_CCSID are the only address families to support the socketpair() API. The socketpair() API returns two socket descriptors that are unnamed and connected.
- After the socket descriptor is received, the connect() API is used to establish a connection to the server.
- The send() API sends 250 bytes of data that are specified in the server application with the SO_RCVLOWAT socket option.
- The recv() API loops until all 250 bytes of the data have arrived.
- The close() API closes any open socket descriptors.