Spring 2021 CSE30264 Programming Assignment 3 - Online Chat Room


Total Points: 100 points
Goal: Program a Prototype of an Online Chat Room
Assigned: March 29, 2021
Due: April 14, 2021 by the end of day (11:59 pm Eastern).
Grouping: To be completed by a group.
Note: This instruction is based on C/C++. The Python version is available at here.

Background

In this programming assignment, you will implement the client and server sides of an "online chat room" application. You can choose to use either TCP or UDP in your implementation. In this application, the client determines the operation to be performed: broadcast messaging and private messaging. Even though only one port is being used, the server should be able to accept multiple simultaneous client connections. The server should respond appropriately to the specific command sent by the client. The specifics of the protocol are detailed in this handout. You are free to reuse part of your programs in PG1 and PG2 to finish this assignment. Please refer to Appendix for the port number assigned to you (same as PG1).

Type of Messages

In this assignment, we define two types of message frames: data message and command message. A data message is the message exchanged between clients (i.e., the broadcast and private messages described in the following online chat room protocol). A command message is the message exchanged between the client and server (e.g., operation, acknowledgment, confirmation messages described below). In your implementation, you can define your own message format to encode the message type. For example, you can use the first character of the message to distinguish between the two types of messages (e.g., "C" for command message and "D" for data message). Note: In your implementation, the sender is responsible for encoding the type information into the message frame and the receiver is responsible for extracting the type information from the message and performing accordingly. (Refer to Technical Instruction section for more details.)

Online Chat Room

  1. Server opens a port, creates the TCP/UDP socket, goes into "wait for connection" state, and actively listens for socket connections. Hint: please read the Technical Instruction section for details.
  2. Client logs in to the system by connecting to the server on the appropriate port.
  3. Client sends the username.
  4. Server checks to see if it is a new user or existing user and requests a password. Note: store users and their passwords in a file rather than in memory (otherwise the credentials will get lost once the server program is terminated).
  5. Server generates a public key and sends it to the client.
  6. Client encrypts its password using server's public key, and sends the encrypted password to server.
  7. Server receives the password and decrypts it. Then, server either registers a new user or checks to see if the password matches. Server also sends the acknowledgment to the client.
  8. Client generates a public key and sends it to the server. Note: multiple clients should be able to register at the same time.
  9. Server continues to wait for operation command from a client or a new client connection.
  10. Client goes into "prompt user for operation" state and prompts user for operation.
  11. Client passes operation (BM: Broadcast Messaging, PM: Private Messaging, EX: Exit) to server.
  12. Operation is executed as follows:
    1. BM:
      1. Client sends operation (BM) to broadcast a message to all active clients (i.e., clients who successfully log in to the system but have not exited yet).
      2. Server sends the acknowledgment back to the client to prompt for the message to be sent.
      3. Client sends the broadcast message to the server.
      4. Server receives the message and sends that broadcast message to all other client connections. Note: the server should keep track of the socket descriptors it has created for each client since the program began running. You can decide how to implement this tracking function.
      5. Server sends the confirmation that the message was sent. Note: you can decide the content/format of the confirmation.
      6. Client receives the confirmation.
      7. Client and server return to "prompt user for operation" and "wait for operation from client" state, respectively.
    2. PM:
      1. Client sends operation (PM) to leave a message to a specific client.
      2. Server sends the list of current online users. Note: the server should keep track of the usernames of all online users (i.e., users associated with active clients) since the program began running. You can decide how to implement this tracking function. We assume that any client can go offline by using operation (EX).
      3. Client receives the list of online users from the server.
      4. Client prompts the user for the username (of the target user) to send a message to.
      5. Client sends the username to the server, and the server replies with the user's public key.
      6. Client then prompts for, encrypts, and sends the message to be sent.
      7. Server receives the above information and checks to make sure the target user exists/online.
      8. If the target user exists/online, the server forwards the message to the user, which decrypts and displays the message. The server should do this by sending the message to the corresponding socket descriptor of the target user.
      9. Server sends the confirmation that the message was sent or that the user did not exist. Note: you can decide the content/format of the confirmation.
      10. Client receives the confirmation from the server.
      11. Client and server return to "prompt user for operation" and "wait for operation from client" state, respectively.
    3. EX:
      1. Client sends operation (EX) to close its connection with the server and end the program.
      2. Server receives the operation and closes the socket descriptor for the client.
      3. Server updates its tracking record on the socket descriptors of active clients and usernames of online users.
      4. Client should close the socket and exit.
Note: If it is not explicitly specified, the client and server will return to "prompt user for operation" and "wait for operation from client" state, respectively after a successful operation and wait for the next operation.

Technical Instructions

General Notes

Server Side Design

The server is responsible for handling the connection request from multiple clients, processing the request, then looping back to handle further requests from any client. The server should listen on the specified port number (refer to Appendix for the port number) that is given by the command-line argument. Your server should bind to the port and then listen for incoming client connections. You may decide if you would like to allow timeouts for better responsiveness but any sort of a timeout is purely optional. You may want to allow for port reuse for quicker recovery after a crash.

Once a new client request arrives, your server should use the accept function to create a new client socket.

The server executable should be named chatserver and be invoked as follows:
[netid@student00 ~] $ ./chatserver Port

Client Side Design

The client is responsible for initiating a connection to a server. Once connected, the client code should prompt the user for an operation (BM, PM, EX), and should transmit the operation to the server.

The client executable should be named chatclient and be invoked as follows:
[netid@student02 ~] $ ./chatclient Server_Name Port Username

The first argument is the hostname of the server to connect to (this will depend on what machine you start your server code on). The second argument is the port number. The third argument is the username for login.

Demo:


Submission

Submit a gzipped tar file of your entire assignment package to your dropbox (i.e., /escnfs/courses/sp21-cse-30264.01/dropbox/yournetid/program3/). The archive must include the following:

Grading Rubric


Appendix

Table 1. Port Assignments
Port to UseName
41001 Joshua Agron
41002 Matthew Ahrens
41003 Emma Ascolese
41004 Julia Blanchard
41005 Brian Cariddi
41006 Maria Carroll
41007 Mark Cheng
41008 Clara Cheong
41009 Megha Devaraj
41010 Theodore Donegan
41011 Ahmed Farag
41012 William Gentry
41013 John Gordley
41014 Emily Grow
41015 Alejandro Jose Gutierrez Elizondo
41016 Jake Hracho
41017 Melka Konshie
41018 Tyler Krasny
41019 Zachary Kreft
41020 Jonathan David Lamptey
41021 Sabin Litchfield
41022 Nicholas Locascio
41023 Keegan MacDonell
41024 John Masciopinto
41025 Jacob Mazur
41026 Mary McCann
41027 Daniel McFarlane
41028 Evan Mercurio
41029 Conor Murphy
41030 Peter Oliver
41031 Ryan Pairitz
41032 Thomas Renfrew
41033 John Rundle
41034 Matthew Shan
41035 Luke Siela
41036 Dane Williams