The sendmsg() and recvmsg() examples
show how to design a server program that uses these APIs to handle incoming
connections.
When the server starts, it creates a pool of worker jobs. These
preallocated (spawned) worker jobs wait until needed. When the client job
connects to the server, the server gives the incoming connection to one of
the worker jobs.
The following figure illustrates how the server, worker, and client
jobs interact when the system uses the sendmsg() and recvmsg() server
design.
Flow of socket events: Server that uses sendmsg() and recvmsg() functions
The
following sequence of the socket calls provides a description of the graphic.
It also describes the relationship between the server and worker examples.
The first example uses the following socket calls to create a child process
with the sendmsg() and recvmsg() function
calls:
- The socket() function returns a socket descriptor representing
an endpoint. The statement also identifies that the INET (Internet Protocol)
address family with the TCP transport (SOCK_STREAM) are used for this socket.
- After the socket descriptor is created, the bind() function
gets a unique name for the socket.
- The listen() allows the server to accept incoming client
connections.
- The socketpair() function creates a pair of UNIX® datagram
sockets. A server can use the socketpair() API to create
a pair of AF_UNIX sockets.
- The spawn() function initializes the parameters
for a work job to handle incoming requests. In this example, the child job
created inherits the socket descriptor that was created by the socketpair().
- The server uses the accept() function to accept an
incoming connection request. The accept() call blocks indefinitely
waiting for the incoming connection to arrive.
- The sendmsg() function sends an incoming connection
to one of the worker jobs. The child process accepts the connection with therecvmsg() function.
The child job is not active when the server called sendmsg().
- In this example, the first close() function closes
the accepted socket. The second close () call ends the
listening socket.
Socket flow of events: Worker job that uses recvmsg()
The
second example uses the following sequence of function calls:
- After the server has accepted a connection and passed its socket descriptor
to the worker job, the recvmsg() function receives the
descriptor. In this example, the recvmsg() function waits
until the server sends the descriptor.
- The recv() function receives a message from the client.
- The send() function echoes data back to the client.
- The close() function ends the worker job.