CS 537, Client-Server Interfaces

Spring 2002 - Test 1


  1. Is the issue of stateful vs. stateless more influential when developing clients or servers? Explain.


    The question of state vs. no state is more influential for the server because dealing with state is more difficult for the server than it is for the client. The server must deal with at least two types of state - the state associated with the service being offered and the state associated with the service's implementation. In addition, the server must keep track of this state on a per-client basis; there may also be some global state associated with the server and service being provided.

    The client, on the other hand, has to deal only with the state provided by the RPC service itself, and need only be concerned with its own state.


  2. Briefly discuss the responsibilities of the client and server in implementing each of the three common RPC calling semantics.


    The three common RPC calling semantics are at least once, at most once, and exactly once.

    The easiest of the three to implement is at least once semantics, and requires that the client periodically retransmit its request until it receives a reply from the server. Once it receives a reply, the client can end server contact with no further action. The server and the RPC protocol need to nothing special.

    Next in difficulty is exactly once semantics. The client behaves as it did with at least once semantics, except it has to add a sequence number to its request so the server can keep track of the outstanding requests. The server is responsible for making sure it executes only one request from each sequence. The server must also remember the reply returned from each request in case the reply gets lost. The RPC protocol has to include sequence fields for the request and reply.

    At most once semantics is similar to exactly once semantics, except the client can stop after some number of unsuccessful retransmissions.


  3. Pick three functions from the sockets API and discuss the possibility and appropriateness of implementing each function without system calls.


    The usual client-side socket API consists of the socket(), connect(), shutdown(), close() and the various stream and datagram I-O system calls. All of these require access to kernel data structures - the file table in particular - either to set them up (socket(), delete them (close()), or to interrogate or manipulate them.

    The usual server-side socket API - bind(), listen(), and accept()), as well as the routines in common with the client - also need access to kernel data structures for the same reasons as the clients.


  4. Explain why and when it is appropriate to augment a concurrent server with an iterative architecture. Which form of concurrency is most appropriate for this kind of modification? Explain.


    The usual justification for increasing concurrency is to handle the instability that results when the request arrival rate grows larger then request service rate. Because the server's already using concurrency, the instability could result from a further increase in arrival rate (or a decrease in service rate) or to external limits that prevent any further concurrency.

    In such situations, it may make sense to multiplex the existing computations over more connections (or clients) by adding an iterative architecture to the server so that each computation handles several connections. If the original architecture is single-threaded concurrent, then the server already is iterative. Multi-threaded concurrency is relatively easy to adapt to an iterative architecture because of the shared address space and resources allow threads to pick up new and release finished clients with a minimum of fuss. Forking concurrency is the least suitable for retrofitting an iterative architecture because it is generally difficult for a worker computation in another process to pick up a new client from the server process.



This page last modified on 15 March 2002.