The LISTEN call actually converts the current socket from “active” to “passive.” This is a one-way conversion. A passive socket cannot be switched back to an active socket. A passive socket cannot be used for sending and receiving data. It only accepts connects, but once it accepts a connection, it will create a new active socket that is used for sending and receiving data. The creation of the new active socket does not destroy the original passive socket. This means that the original socket can continue to accept new connections, each new connection creating a new active socket.
To indicate to the IP stack that your program is ready to communicate, the program must issue an ACCEPT call. Once someone requests a connection against your server, an ACCEPT will complete. The retcode field will contain the number of the newly created active socket. This new socket has a connection already established and the program can immediately issue any send or receive requests. It must also be closed when all transmissions are complete. The CLOSE for this new socket does not affect the original socket used by the ACCEPT. An example of an ACCEPT call is shown in lines 129 through 137 of Figure 6.
Figure 13 shows the basic code for a simple server. Note that it saves the original socket number on line 11 and you always use it for any ACCEPT calls (line 25). The original socket is also closed on lines 50 through 53. As a server normally receives requests, the RECV and SEND calls are reversed when compared to Figure 11. Lines 44 through 49 show that the new active socket is closed and then the server loops back up to the ACCEPT call to process any new connection requests.
SELECTing in a Server
When creating the client program, I discussed how the READ would appear to hang if the server did not respond. A server also needs to handle the condition where a connection is requested, but the client never sends a request. You can insert code to perform a SELECT call similar to Figure 12 into Figure 13 prior to line 31.
In addition, an ACCEPT call will not complete until someone requests a connection. If you insert the SELECT code in Figure 5 into Figure 6 prior to line 26, the program can gain control whenever a timeout condition exists. Once a timeout occurs, the program can check for a CICS shutdown condition. If CICS is not performing a shutdown, the program can just loop back to the SELECT and wait for a connection request.
There are two different types of servers. The simple server I have just discussed is an example of an iterative server because it processes requests from clients serially, or “one at a time.” In contrast, a concurrent server accepts connection requests and then passes the connection to a separate child program. This allows the server to immediately process additional connection requests. If the request is seldom used or is simple, and therefore quick, an iterative server might be all that is needed, but most servers need to be written as concurrent servers. Figure 14 shows the process flow between a client, a concurrent server, and a child.