using AF_UNIX address family

11:19:00 PM 0 Comments

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.

An example path name that an application might use for this address family is /tmp/myserver or servers/thatserver. With servers/thatserver, you have a path name that is not fully qualified (no / was specified). This means that the location of the entry in the file system hierarchy should be determined relative to the current working directory.
Note: Path names in the file system are NLS-enabled.

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.

Socket flow of events: Server application that uses AF_UNIX address family

The first example uses the following sequence of API calls:

  1. 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.

  2. 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.

  3. 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.
  4. 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.
  5. The send() API echoes the data back to the client.
  6. The close() API closes any open socket descriptors.
  7. 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:

  1. 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.

  2. After the socket descriptor is received, the connect() API is used to establish a connection to the server.
  3. The send() API sends 250 bytes of data that are specified in the server application with the SO_RCVLOWAT socket option.
  4. The recv() API loops until all 250 bytes of the data have arrived.
  5. The close() API closes any open socket descriptors.

creating a connectionless socket

11:18:00 PM 0 Comments

creating a connectionless socket

Connectionless sockets do not establish a connection over which data is transferred. Instead, the server application specifies its name where a client can send requests.

Connectionless sockets use User Datagram Protocol (UDP) instead of TCP/IP.

The following figure illustrates the client/server relationship of the socket APIs used in the examples for a connectionless socket design.

The client/server relationship of the socket APIs for a connectionless protocol

Socket flow of events: Connectionless server

The following sequence of the socket calls provides a description of the figure and the following example programs. It also describes the relationship between the server and client application in a connectionless design. Each set of flows contains links to usage notes on specific APIs. If you need more details on the use of a particular API, you can use these links. The first example of a connectionless server uses the following sequence of API calls:

  1. The socket() API returns a socket descriptor, which represents an endpoint. The statement also identifies that the Internet Protocol address family (AF_INET) with the UDP transport (SOCK_DGRAM) is used for this socket.
  2. After the socket descriptor is created, a bind() API gets a unique name for the socket. In this example, the user sets the s_addr to zero, which means that the UDP port of 3555 is bound to all IPv4 addresses on the system.
  3. The server uses the recvfrom() API to receive that data. The recvfrom() API waits indefinitely for data to arrive.
  4. The sendto() API echoes the data back to the client.
  5. The close() API ends any open socket descriptors.

Socket flow of events: Connectionless client

The second example of a connectionless client uses the following sequence of API calls.

  1. The socket() API returns a socket descriptor, which represents an endpoint. The statement also identifies that the Internet Protocol address family (AF_INET) with the UDP transport (SOCK_DGRAM) is used for this socket.
  2. In the client example program, if the server string that was passed into the inet_addr() API was not a dotted decimal IP address, then it is assumed to be the host name of the server. In that case, use the gethostbyname() API to retrieve the IP address of the server.
  3. Use the sendto() API to send the data to the server.
  4. Use the recvfrom() API to receive the data from the server.
  5. The close() API ends any open socket descriptors.

creating a connection-oriented socket

11:17:00 PM 0 Comments

creating a connection-oriented socket

These server and client examples illustrate the socket APIs written for a connection-oriented protocol such as Transmission Control Protocol (TCP).

The following figure illustrates the client/server relationship of the sockets API for a connection-oriented protocol.

The client/server relationship of the sockets API for a connection-oriented design

Socket flow of events: Connection-oriented server

The following sequence of the socket calls provides a description of the figure. It also describes the relationship between the server and client application in a connection-oriented design. Each set of flows contains links to usage notes on specific APIs.

  1. The socket() API returns a socket descriptor, which represents an endpoint. The statement also identifies that the Internet Protocol address family (AF_INET) with the TCP transport (SOCK_STREAM) is used for this socket.
  2. The setsockopt() API allows the local address to be reused when the server is restarted before the required wait time expires.
  3. After the socket descriptor is created, the bind() API gets a unique name for the socket. In this example, the user sets the s_addr to zero, which allows connections to be established from any IPv4 client that specifies port 3005.
  4. The listen() API 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.
  5. The server uses the accept() API to accept an incoming connection request. The accept() call blocks indefinitely, waiting for the incoming connection to arrive.
  6. The select() API allows the process to wait for an event to occur and to wake up the process when the event occurs. In this example, the system notifies the process only when data is available to be read. A 30-second timeout is used on this select()call.
  7. The recv() API receives data from the client application. In this example, the client sends 250 bytes of data. Thus, the SO_RCVLOWAT socket option can be used, which specifies that recv() does not wake up until all 250 bytes of data have arrived.
  8. The send() API echoes the data back to the client.
  9. The close() API closes any open socket descriptors.

Socket flow of events: Connection-oriented client

The following sequence of APIs calls describes the relationship between the server and client application in a connection-oriented design.

  1. The socket() API returns a socket descriptor, which represents an endpoint. The statement also identifies that the Internet Protocol address family (AF_INET) with the TCP transport (SOCK_STREAM) is used for this socket.
  2. In the client example program, if the server string that was passed into the inet_addr() API was not a dotted decimal IP address, then it is assumed to be the host name of the server. In that case, use the gethostbyname() API to retrieve the IP address of the server.
  3. After the socket descriptor is received, the connect() API is used to establish a connection to the server.
  4. The send() API sends 250 bytes of data to the server.
  5. The recv() API waits for the server to echo the 250 bytes of data back. In this example, the server responds with the same 250 bytes that was just sent. In the client example, the 250 bytes of the data might arrive in separate packets, so the recv()API can be used over and over until all 250 bytes have arrived.
  6. The close() API closes any open socket descriptors.