R. E. Newman, University of Florida
Project 2 - Multi-threaded Client-Server
DUE: February 19, 2014
Overview
Your first programming project was to write a simple server and a client
using socket programming. For Project 2, you will revise that program to make both the client and the server multi-threaded. This will enable the server to handle multiple clients at the same time, and to maintain a persistent connection with a given client. It will also allow each server to contact other servers as a client in C-S communications, to exchange information with them as needed. Clients will also be able to receive multiple responses, and receive them from servers other than the one to which they initially connected.
The program may be written in C, C++, or Java.
Actual files must be used for this project if they were not used in Project 1.
A client will connect to a server, send the server requests to upload, read-lock, write-lock, release a lock, read, write, or delete a file from the system of servers. The client must also explicitly disconnect from the server when it is done, either due to the user making this request or the client process terminating.
The server will receive connection requests from one or more clients, and carry out the request if possible. In addition, servers will receive connection requests from other servers that forward requests from other clients.
An upload request for a file with the same name must produce an error unless the client holds a write lock on the file, in which case the existing file may be overwritten (the server may warn the client, which may ask the user whether to replace, make a second file with an altered name, or abort).
Each server will run in its own local directory, and will only access files in that directory directly. The servers must partition responsibilty for the uploaded files among themselves (e.g., by file name or by hash value), and a request to access a file that is not the responsibility of the requested server must result in the requested server forwarding (either directly or indirectly) the client's request to the server that is responsible. Contact information for the client must be included so that when the responsible server eventually receives the request, it can contact the client and provide an appropriate response.
The client may persist to send a sequence of requests to one or more servers. A client must be able to connect to one server and receive connections from it or from other servers that are forwarded the client's request. This will require that the client start at least two threads - one to make requests of a server to which it is connected persistently, and one to receive responses from the server responsible for the file the client has requested to access.
Servers must persist until they receive a request to terminate, handling requests from multiple clients and from other servers at the same time using multiple threads.
Program Requirements:
- Your client and server must compile and run on the CISE lab hosts. You may test this by using remote access (e.g., PuTTY) and running several servers and several clients remotely.
- Use TCP sockets on both ends of the connections.
- Servers and cients must be able to resolve the name of a machine into its
IP address.
- Your client must have a simple command line interface (CLI) to allow for
user interaction.
- The client must accept a server's address and port from the
command line interface, from a configuration file, and from the client command line. The address and port must be determined at runtime. The address may either be the IP address
or a fully qualified domain name.
- The client must be able to disconnect from a server to which it is currently conencted from its CLI.
- The client must be able to connect to another server from its CLI without disconnecting from the server(s) to which it is currently connected. If a client is connected to multiple servers, the CLI must provide a way for the user to specify to which server a request should be sent, or to use a default server.
- The server must determine the port on which it will listen from the
command line.
- The server must be able to obtain information about other servers from the command line, from a configuration file, and from other servers. This information must be dynamically updated as other servers come and go, and a server must not maintain information on more than three other servers at a time.
- The servers must organize themselves in such a way that the responsibility for the files they manage is distributed over the servers, and that the loss of any server (with its local directory) will not result in loss of access to any file that has been uploaded but not deleted.
- The servers must ensure that locks are handled correctly amongst themselves, so that if one server grants a lock on file X, no other server can grant a conflicting lock on X.
- The servers must maintain redundant lock information as well, so that the loss of one server does not result in loss of lock information.
- The server must loop, accepting connections and requests from clients indefinitely until it receives a request to exit.
On each connection setup, connection teardown, or request, the server must print to stdout information on the client (or other server) it is servicing (IP, port#), then the request, then the action it has taken,
followed by a newline.
- The server must accept and carry out requests if possible.
- A request for any lock shall be granted if the file has no locks on it.
- A read-lock will be granted if the file does not have a write-lock on it.
- A file that already had a write-lock cannot be locked again until the write-lock is released.
- Only the client that was granted a lock can release that lock.
- The server must accept and carry out requests to print out all files it currently has, any locks held on each file, and last modification time.
- The server must also accept and carry out a request to exit cleanly.
- All ports should be released before your program exits.
- The client should report and handle all reasonable error conditions.
- The server should report and handle all reasonable error conditions.
Documentation Requirements:
- The code must include reasonable comments describing its actions.
- Include a REPORT file. In addition to the elements described on the
projects page, it should include:
- 1. What your system does
- 2. A description what processes are involved and how
- 3. A description what state is maintained by each process
- 4. A description of each message type that is exchanged
- 5. A description what actions are taken upon receipt of each message
- 6. A description when a given message type is generated
- 7. User interface (if any) to each process type
- 8. Test runs used to test elements of your system, along with
expected (or actually generated) output.
- Include a README file:
- 1. A synopsis, describing how your client/server is invoked
- 2. A list of any known bugs
- 3. A list of extra features
- Please make sure your README is short and concise.
- If appropriate, include a makefile with the following targets:
- 1. all, to compile both the client and the server
- 2. clean, to remove *~ *.o and core files
- submit the project (all files) by creating a single archive file and
submitting on Sakai.
Bonus
An extra 20% bonus is avaliable if you also submit a Scala version within one week of the project due date.
Q and A