Project Specification:
You may write the program in any language that is supported under any Integrated Development Environment (IDE). Keep in mind that available controls, objects, libraries, et cetera, may make some of these tasks easier in one language than in another.
All components should be managed with a simple GUI. The GUI should provide a way to kill the process without using the 'exit' button on the window.
You will implement a message service consisting of a server process and three clients. Each client process will connect to the server over a socket. The server should be able to handle all three clients concurrently.
Clients will prompt the user for a username. When a client connects to the server, its username should be displayed by the server in real time. Two or more clients may not use the same username simultaneously. Should the server detect a concurrent conflict in username, the client's connection should be rejected, and the clients user should be prompted to input a different name.
The server will keep a cumulative log of previously used usernames and display those names on its GUI. The server should indicate which of those usernames represent clients presently connected to the server and which are not connected. Clients may reuse usernames and a client reusing an extant username should not be treated as a duplicate in the log.
When a client connects to the server, the server should provide the log of usernames to the client. The user will then be prompted to select from one of three options:
- Send message to specific username (1-to-1)
- Send message to a subset of usernames (1-to-n)
- Send a message to all usernames (1-to-all)
Message Server
If a user selects options 1 or 2, it is the developer's discretion with regards to how the user indicates their selection. If the user indicates their selection by typing a string, the client should reject that string if it does not match an entry in the list received from the server.
Once the user has selected the intended recipient(s), the user should be prompted to enter a brief text message. When the user has finished, the text message should be uploaded to the server. When the server receives the message from the client, it should check the intended recipient(s) against the list of presently connected clients.
- If the targeted client is present, the message should be sent to that targeted client and presented on the client's GUI. The originating client should be noted on the message.
- If the targeted client is not present, the originating client should be notified, and the user should be informed via the client's GUI.
The client should remain connected to the server until manually disconnected by the user.
The required actions are summarized below.
Client
Startup:
- Prompt the user to input a username.
- Connect to the server over a socket and register the username.
- When the client is connected, the user should be notified of the active connection.
- If the provided username is already in use, the client should disconnect and prompt the user to input another username.
- Proceed to send and receive messages until manually killed by the user.
Sending Messages:
- The client will present the list of usernames received by the server to the user.
- The user will be prompted to select from one of the three messaging options listed above.
- The user will be prompted to select their intended recipient(s).
- After the recipients are selected, the user should be prompted to input a brief text message.
- The client will upload the text message to the server.
- Return to Sending Messages: Step 1 until manually disconnected by the user.
Receiving Messages:
- When connected to the server, the client will listen for incoming text messages.
- Upon receipt of a text message, the client will print the text message to the GUI. The text message should indicate from which username the message was received.
- Return to Receiving Messages: Step 1 until manually disconnected by the user.
Server
The server should support three concurrently connected clients. A cumulative log of all previously used usernames should be maintained by the server and presented on the server's GUI. The server should indicate which of those usernames (if any) represent currently connected clients. The server will execute the following sequence of steps:
- Startup and listen for incoming connections.
- Print that a client has connected, log the client's username, and:
- If the client username is available (e.g., not currently being used by another client), fork a thread to handle that client. Or,
- If the username is in use, reject the connection from that client.
- When a client connection is accepted, the server should provide the log of usernames to the client.
- When a text message is received from a client, the server should:
- Forward that message to the intended recipients, if those recipients are connected. Or,
- Indicate the present recipients are not presently connected to the server.
- Begin at step 2 until the process is killed by the user.
Notes:
- All three clients and the server may run on the same machine.
- It is not necessary for the server to store a copy of messages after they have been delivered to their intended recipients.
- The server must correctly handle an unexpected client disconnection without crashing.
- When a client disconnects from the server, the server GUI must indicate this to the user in real time.
- The program must operate independently of a browser.