This project is a part of Operating Systems I CMPT 300 course at Simon Fraser University.
In this project, I developed a simple Linux-based chat system, enabling communication between users on
distinct terminals. Core Linux concepts, such as Threads and the
User Datagram Protocol (UDP), were harnessed during the development process. The architecture
was built using Pthreads, known for its kernel-level thread implementation in
Linux, while interprocess communication was facilitated by datagram sockets
utilizing UDP.
The chat system operates through two Linux processes, each initialized by a
different user. Each process consists of four threads. The first thread handles
keyboard input, the second thread awaits incoming UDP datagrams, the third thread
manages message printing, and the fourth thread is responsible for transmitting
data to the remote Unix process over the network using UDP. The processes can
run on different machines and communicate via the internet.
The threads share access to an Abstract Data Type (ADT) list. This list holds
messages that need to be either sent to the remote chat client or printed to the
local screen. The input thread adds keyboard input to the list, while the UDP
sender thread pulls from the list to send messages to the remote client. The UDP
receiver thread, upon receiving a message, adds it to the print list, and the
console output thread prints each received message.
The system supports command-line arguments, which define the IP address and port
number of the remote client as well as the port number for listening to incoming
UDP packets. The program was structured to be executed with the format: `lets-talk
[my port number] [remote/local machine IP] [remote/local port number]`.
Additionally, the project integrated a simple cipher encryption/decryption
mechanism with a fixed key, along with online status checking functionality.
The chat system also supports sending and receiving long lines of text, as well
as quitting the connection with the "!exit" command. This command results in a
clean termination of the program on both terminals. The system was optimized to
avoid deadlock and infinite loops, thereby ensuring efficient CPU usage.
The project was developed following best coding practices, such as checking
return values on all socket functions, appropriately using `fflush(stdout)`,
and passing Valgrind checks for memory leak detection and clean program
termination. This helped to ensure the robustness and reliability of the
implemented chat system.