This topic contains concepts and tasks information about passing
sockets.
Common interface concepts
To help you better understand socket passing, the following topics
explain common interface concepts.
- Blocking versus nonblocking
A socket is in blocking
mode when an I/O() call waits for an event to complete. If blocking
mode is set for a socket, the calling program is suspended until the
expected event completes.
If nonblocking is set by calls FCNTL()
or IOCTL(), the calling program continues even though the I/O() call
might not have completed. If the I/O() call could not be completed,
it returns with ERRNO 35 (EWOULDBLOCK). The calling program should
use select() to test for completion of any socket call returning an
ERRNO 35.
The default mode is blocking.
- If data is not available for the socket, and the socket is in
blocking and synchronous modes, the read() call blocks the caller
until data arrives.
- Concurrent servers versus iterative servers
An iterative
server handles one client at a time. A concurrent server receives
connection requests from multiple clients and creates subtasks to
process those client requests.
When a subtask is created,
the concurrent server gets a new socket, passes the new socket to
the subtask, and disassociates itself from the connection. (The CICS® listener program is an example
of a concurrent server.)
- To pass a socket, the concurrent server first calls givesocket().
If the subtask address space name and subtask ID are specified in
the givesocket() call, only a subtask having a matching address space
and subtask ID can take the socket. If this field is set to blanks,
any MVS™ address space requesting
a socket can take this socket.
- The concurrent server starts the subtask and passes to it the
socket descriptor and concurrent server ID obtained from earlier socket()
and getclientid() calls.
- The subtask calls takesocket() using the concurrent server ID
and socket descriptor.
- The concurrent server issues the select() call to test the socket
for the takesocket-completion exception condition.
- When takesocket() has successfully completed, the concurrent server
issues the close() call to free the socket.
- If the queue has no pending connection requests, accept() blocks
the socket when blocking mode is set on. You can set the socket to
nonblocking by calling FCNTL or IOCTL.
- Issuing a select() call before the accept() call ensures that
a connection request is pending. Using the select() call in this way
prevents the accept() call from blocking.
- TCP⁄IP does not screen clients, but you can control the connection requests
accepted by closing a connection immediately after you determine the
identity of the client.
- A given TCP⁄IP host can have multiple aliases and multiple host internet
addresses.
A server handling more than one client simultaneously
acts like a dispatcher at a messenger service. A messenger dispatcher
gets telephone calls from people who want items delivered, and the
dispatcher sends out messengers to do the work. In a similar manner,
the server receives client requests, and then spawns tasks to handle
each client.
Tasks can pass sockets with the givesocket() and
takesocket() calls. The task passing the socket uses givesocket(),
and the task receiving the socket uses takesocket(). The following
topics describe these processes.