z/OS Communications Server: IP Sockets Application Programming Interface Guide and Reference
Previous topic | Next topic | Contents | Contact z/OS | Library | PDF


Accepting client connection requests in an iterative server program

z/OS Communications Server: IP Sockets Application Programming Interface Guide and Reference
SC27-3660-00

To this point in the process, the server has allocated a socket, bound the socket to an IP address and port, and issued a passive open. The next step is for the server to connect with a client. The accept() call blocks the server until a connection request arrives; if there are connection requests in the backlog queue, a connection is established with the first client in the queue. The following example shows the accept() call:
client_sock = accept(s);
The server passes its socket to the accept call. When the connection is established, the accept call returns a new socket representing the connection with the client. When the server wants to communicate with the client, or to end the connection, it uses this new socket, client_sock. The original socket s is now ready to accept connection to other clients. The original socket is still allocated, bound, and passively opened. To accept another connection, the server calls accept() again. By repeatedly calling accept(), the server can establish simultaneous sessions with multiple clients.

The accept() call dequeues the first queued connection request or blocks the caller until a connection request arrives over the IP network.

The accept() call uses the variables listed in Figure 1.

Figure 1. Variables used by the ACCEPT call
*---------------------------------------------------------------*
* Variables used by the ACCEPT Call                             *
*---------------------------------------------------------------*
   01  client-socket-address.
       05  client-afinet              pic 9(4) binary value 0.
       05  client-port                pic 9(4) binary value 0.
       05  client-ipaddr              pic 9(8) binary value 0.
       05  filler                     pic x(8) value low-value.
   01  accepted-socket-descriptor     pic 9(4) binary value 0.
   01  socket-descriptor              pic 9(4) binary.
*---------------------------------------------------------------*
* Start iterative server loop with a blocking Accept Call       *
*---------------------------------------------------------------*
  call 'EZASOKET' using soket-accept
    socket-descriptor
    client-socket-address
    errno
    retcode.
  if retcode < 0 then
     - process error -
  else
     Move retcode to accepted-socket-descriptor.  

This call works with the following socket descriptors:

  • The first socket descriptor represents the socket that was obtained, bound to the server port and (optionally) the IP address, and changed to the passive state using the listen() call.
  • The accept() call returns a new socket descriptor, to represent a complete association:
    Accepted_socket_descriptor represents:
    {TCP, server IP address, server port, client IP address, client port} 
The original socket, which was passed to the accept() call, is unchanged and is still representing our server half association only:
Original_socket_descriptor represents:
{TCP, server IP address, server port}    

When control returns to your program, the socket address structure passed on the call has been filled with the socket address information of the connecting client. Figure 2 illustrates the socket states.

Figure 2. Socket states
After the iterative server accepts client connection requests, the new socket represents a fully bound socket with both local and remote addresses.

When a socket is created, we know the protocol that we are going to use with this socket, but nothing else. When a server calls the bind() function, a local address is assigned to the socket, but the socket still only represents a half-association; the remote address is still empty. When the client connects to the listener socket and a new socket is created, this new socket represents a fully bound socket possessing both a local address (that of the listener socket) and a remote address (that of the client socket). Figure 2 illustrates a fully bound socket.

Subsequent socket calls for the exchange of data between the client and the server use the new socket descriptor. The original socket descriptor remains unused until the iterative server has finished processing the client request and closed the new socket. The iterative server then reissues the accept() call using the original socket descriptor and waits for a new connection.

Go to the previous page Go to the next page




Copyright IBM Corporation 1990, 2014