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.
*---------------------------------------------------------------*
* 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:
Accepted_socket_descriptor represents:
{TCP, server IP address, server port, client IP address, client port}
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.
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.