Skip to content

Prince-Patel84/Terminal-based-Chatting-System

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚀 Terminal-Based Chat System

This project is a multi-user, terminal-based chat application written entirely in C. It allows users on a local network to dynamically discover and join password-protected chat rooms. The entire application is compiled into a single executable (app), which can act as either a Host (server) or a Joiner (client).

This project was built to demonstrate a deep understanding of core computer systems programming concepts, including low-level socket programming, multithreading, and concurrency management.


🧑‍💻 Project Team

Name Student ID GitHub ID
Prince Patel 202401151 Prince-Patel84
Purvi Nakum 202401172  Purvi917
Sejal Patel 202401155 SejalPatel01
Vishwa Prajapati 202401163 Vishwa7399

🌟 Key Features

  • Single Executable: A single app binary handles both hosting and joining.
  • Host/Join Menu: A simple command-line menu for users to select their role.
  • Dynamic Room Discovery: "Joiner" clients automatically scan and display a list of available rooms on the local network.
  • Password Protection: Hosts are given a unique, 6-digit password for their room, which joiners must provide.
  • Multi-User Chat: Supports a host and multiple clients chatting in real-time.
  • Host as Participant: The user who hosts a room is also a participant in the chat.
  • Robust & Modular Design: The code is professionally structured to separate concerns (networking, chat UI, host logic, join logic).

🧠 Core Computer Systems Concepts

This project is a practical application of several key computer systems programming (CSP) concepts.

1. Socket Programming (TCP & UDP)

The application's networking layer is built from the ground up using the low-level BSD socket API. We strategically used both of the main internet protocols for different tasks:

  • TCP (Transmission Control Protocol):

    • Analogy: A phone call. It's reliable, connection-based, and guarantees messages arrive in the correct order.
    • Use Case: We use TCP for the chat itself (Port 8080). It's essential that chat messages are delivered reliably and in the order they were sent.
    • System Calls: socket(AF_INET, SOCK_STREAM, ...), bind(), listen(), accept(), connect().
  • UDP (User Datagram Protocol):

    • Analogy: A postcard or a "shout." It's connectionless, fast, and "fire-and-forget." Packets are not guaranteed to arrive.
    • Use Case: We use UDP for room discovery (Port 8888). The Host periodically "broadcasts" a small packet with the room name and password. This is highly efficient, and if a "Joiner" misses one packet, they'll catch the next one a few seconds later.
    • System Calls: socket(AF_INET, SOCK_DGRAM, ...), setsockopt(SO_BROADCAST), sendto(), recvfrom().

2. Advanced Multithreading (pthreads)

This project relies heavily on pthreads to handle multiple tasks concurrently without blocking the user.

  • The Problem: A single-threaded program can only do one thing at a time. If the program is waiting for keyboard input, it can't simultaneously receive a message from the server.
  • Our Solution: We use threads to manage these conflicting tasks.
    • Joiner Client: A simple 2-thread design.
      • Main Thread: Runs start_client_sender() to read keyboard input.
      • Receiver Thread: Runs start_client_receiver() to wait for and print server messages.
    • Host Application: A complex, multi-threaded hybrid server/client.
      • Main Thread: Becomes the Host's client (runs start_client_sender).
      • Server Listener Thread: Runs server_listener_thread(), which blocks on accept() to receive new clients.
      • Broadcast Thread: Runs broadcast_room_thread(), which sleep()s and sends UDP packets.
      • Host Receiver Thread: Runs start_client_receiver() for the Host's client.
      • Client Handler Threads: The server spawns a new handle_client_thread() for every client that connects.

3. Concurrency and Synchronization (Mutexes)

Because our Host has multiple threads, we have a "shared resource" problem: the global client_list array.

  • The Problem (Race Condition): What if Client A and Client B connect at the exact same time?
    1. Thread A (for Client A) checks client_list and sees the next open spot is client_list[0].
    2. Before it can write, the OS switches tasks.
    3. Thread B (for Client B) checks client_list and also sees the next open spot is client_list[0].
    4. Thread B writes its data.
    5. The OS switches back. Thread A writes its data, overwriting Client B.
    6. Result: Our list is corrupted, and Client B is lost.
  • Our Solution (pthread_mutex_t): We use a Mutex (client_list_mutex) as a "lock" to protect the client_list.
    • Any function that touches the list (like add_client_to_list, remove_client_from_list, broadcast_message_to_all, is_name_duplicate) must call pthread_mutex_lock() first.
    • This ensures only one thread can modify the list at a time, making our server thread-safe.

4. Custom Network Protocol Design

We designed a robust, line-based protocol to solve the "TCP streaming" bug.

  • The Problem: TCP is a stream, not a series of messages. If we write("PASS") and then write("NAME"), the receiver might get "PASSNAME" in a single read(). This breaks our logic.
  • Our Solution: We enforce that every message must end with a newline (\n).
    1. We created a helper function, read_line_from_socket(), which reads one byte at a time from a socket until it finds a \n, then returns a clean string.
    2. All senders (write(), snprintf()) are careful to add a \n to the end of every message, including auth, chat, and system messages.
    3. All receivers (start_client_receiver, handle_client_thread) use read_line_from_socket() to get one complete, clean message at a time.

5. Build Automation (Makefile)

The project uses a Makefile to automate compilation.

  • It tracks dependencies (.c files, .h files).
  • It links all object files (.o) into the final app executable.
  • It correctly passes the -pthread flag, which is essential for linking the pthreads library.

🏗️ Project Architecture

The code is separated into five logical modules for clarity and reusability.

File Module Responsibility
chatapp.c Main The main entry point. Its only job is to display the "Host/Join" menu.
host.h / host.c Host Module Contains all logic for Hosting a room. This includes starting the server threads, managing clients, and the Host's personal client logic.
join.h / join.c Join Module Contains all logic for Joining a room. This includes network scanning, displaying the room list, and the authentication process.
chat.h / chat.c Chat UI Module Provides the client-side functions (start_client_sender, start_client_receiver). This is the "UI" of the chat, responsible for keyboard input and screen output.
networking.h / networking.c Networking Library The core engine. Provides all low-level TCP and UDP functions (setup_tcp_server, connect_to_server, send_broadcast, read_line_from_socket, etc.).

📡 Network Protocol Definitions

We designed three custom protocols for our application's services.

1. Discovery Protocol (UDP - Port 8888)

  • Purpose: To advertise a room's existence.
  • Sender: Host
  • Receiver: Joiner
  • Format: A single plain-text packet: [RoomName]
  • Example: My Test Room

2. Authentication Protocol (TCP - Port 8080)

  • Purpose: To verify a new client and register their name.
  • Flow: This is a strict, line-by-line exchange.
    1. Client: Sends [Password]\n
    2. Client: Sends [Name]\n
    3. Server (On Success): Sends ACCEPT\n
    4. Server (On Failure): Sends REJECT_NAME\n (if name is a duplicate) or closes the connection (if password is wrong).

3. Chat Protocol (TCP - Port 8080)

  • Purpose: To send and receive chat messages after authentication.
  • Format: All messages are single-line, \n-terminated strings.
  • Examples:
    • [prince]: Hello world!\n (Sent by a client)
    • [System] Host has joined the room.\n (Sent by the server)

🛠️ How to Build and Run

1. Build

A Makefile is provided for easy compilation.

# Clean any old build files
make clean

# Compile the project
make all

About

This is our CSP project in which we have made a terminal based chatting system which can work on local networks and uses CSP concepts.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors