Skip to content

kunaljit3006/TerminalTalk

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

💬 TerminalTalk — A Multithreaded Java Chat Server

A real-time, terminal-based chat application built from scratch using Java Sockets and Multithreading. No frameworks, no libraries — just pure Java networking.

TerminalTalk allows multiple users to connect to a central server, chat in a public room, send private messages, and see who is online — all from the command line.


🎯 Why I Built This

I wanted to go beyond just reading about the OSI model and TCP/IP in textbooks. This project forced me to actually implement those concepts — opening sockets, managing byte streams, handling concurrent connections, and designing my own application-layer protocol. Every line of code in this project maps directly to a Computer Networks concept.


🏗️ Architecture

TerminalTalk follows the Client-Server Architecture, one of the most fundamental models in computer networking.

 ┌──────────────┐         TCP Connection         ┌──────────────────────────┐
 │   Client 1   │ ◄────────────────────────────► │                          │
 │  (Terminal)   │                                │                          │
 └──────────────┘                                │                          │
                                                 │     TerminalTalk Server  │
 ┌──────────────┐         TCP Connection         │                          │
 │   Client 2   │ ◄────────────────────────────► │   - Accepts connections  │
 │  (Terminal)   │                                │   - Manages user list    │
 └──────────────┘                                │   - Routes messages      │
                                                 │   - Handles commands     │
 ┌──────────────┐         TCP Connection         │                          │
 │   Client 3   │ ◄────────────────────────────► │                          │
 │  (Terminal)   │                                │                          │
 └──────────────┘                                └──────────────────────────┘

How It Works (Step by Step)

  1. Server starts and opens a ServerSocket on port 8080, waiting for incoming connections.
  2. Client connects by creating a Socket pointed at the server's IP and port.
  3. TCP Handshake happens automatically under the hood (SYN → SYN-ACK → ACK), establishing a reliable connection.
  4. Server spawns a new thread (via a Thread Pool) dedicated to this client. This thread runs a ClientHandler that reads and writes messages for that specific user.
  5. Client runs two threads of its own:
    • Listener Thread — constantly reads incoming messages from the server and prints them.
    • Main Thread — reads keyboard input and sends it to the server.
  6. Messages are routed by the server: broadcast to all users, or sent privately to one user based on the command.
  7. On disconnect, the server removes the user from the active list and notifies everyone.

📂 Project Structure

TerminalTalk/
│
├── Server.java          # The central server — listens, accepts, and manages connections
├── ClientHandler.java   # Runs on a separate thread for each connected user
├── Client.java          # The program users run to connect and chat
└── README.md            # You are here
File Responsibility
Server.java Opens a ServerSocket on port 8080. Maintains a thread-safe map of active users (ConcurrentHashMap). Provides helper methods for broadcasting and private messaging.
ClientHandler.java Implements Runnable. Handles username registration, message parsing, command execution (/msg, /users, /quit), and clean disconnection.
Client.java Connects a Socket to the server. Uses a daemon listener thread for incoming messages and the main thread for user input.

🌐 Computer Networks Concepts Used

This project directly implements the following concepts from a Computer Networks course:

1. Client-Server Model (Network Architecture)

The entire application is built on the Client-Server paradigm. The server is a passive entity that listens for requests, while clients are active entities that initiate connections. This is the same model used by HTTP, FTP, SMTP, and most internet services.

2. TCP/IP (Transport Layer)

All communication uses TCP (Transmission Control Protocol) via Java's Socket and ServerSocket classes.

Why TCP and not UDP?

  • TCP guarantees reliable, ordered delivery of data. In a chat app, we cannot afford messages being dropped or arriving out of order.
  • TCP provides flow control and error detection through checksums and acknowledgments.
  • UDP would be faster but unreliable — suitable for video streaming or gaming, not text messaging.

Under the hood, every connection begins with the TCP 3-Way Handshake:

Client                    Server
  │──── SYN ─────────────►│
  │◄─── SYN-ACK ──────────│
  │──── ACK ─────────────►│
  │                        │
  │   Connection Established

3. Sockets (Network Programming Interface)

A socket is the endpoint for communication between two machines. It is identified by an IP Address + Port Number pair.

  • ServerSocket(8080) — binds the server to port 8080 and listens for connections.
  • Socket("localhost", 8080) — the client creates a socket connecting to the server.
  • Each socket provides an InputStream (to read data) and an OutputStream (to write data), forming a full-duplex communication channel.

4. Port Numbers (Transport Layer Addressing)

Port 8080 is used to uniquely identify this application on the machine. The OS uses port numbers to demultiplex incoming packets — directing web traffic (port 80) to the browser and our chat traffic (port 8080) to TerminalTalk.

5. Application-Layer Protocol Design

The commands /msg, /users, and /quit form a custom Application-Layer Protocol. Just like HTTP defines GET and POST, our protocol defines rules for how the client and server exchange information:

Command Protocol Action
Plain text Server broadcasts to all connected clients
/msg [user] [text] Server performs a unicast — sends only to the target user
/users Server responds with the current list of active connections
/quit Client signals graceful termination; server cleans up resources

6. Concurrent Connections (Multithreading)

A real-world server must handle thousands of simultaneous connections. A single-threaded server can only serve one user at a time — everyone else waits in line.

We solve this using a Thread Pool (ExecutorService):

                      ┌─── Thread 1 ──► ClientHandler (User A)
                      │
Server.accept() ──────┼─── Thread 2 ──► ClientHandler (User B)
                      │
                      └─── Thread 3 ──► ClientHandler (User C)

7. Thread Safety (Concurrency Control)

When multiple threads access shared data (like the list of active users), race conditions can occur. We prevent this using ConcurrentHashMap, which allows safe concurrent reads and writes without explicit locking.


🚀 How to Run Locally

Prerequisites

  • Java JDK 8 or higher installed on your machine.
  • Verify by running: java -version

Step 1: Compile

Open a terminal and navigate to the project folder:

cd "C:\Users\kkuna\Desktop\Computer_netwroks project"
javac Server.java ClientHandler.java Client.java

Step 2: Start the Server

Run the server in one terminal window:

java Server

You should see:

===========================================
   TerminalTalk Server is starting up...
===========================================
[SERVER] Listening on port 8080...
[SERVER] Waiting for users to connect.

Step 3: Connect Clients

Open 2 or more additional terminal windows and run:

cd "C:\Users\kkuna\Desktop\Computer_netwroks project"
java Client

Each client will be prompted for a username. Once connected, start chatting!

Step 4: Try It Out

> Hello everyone!                        # broadcasts to all users
> /msg Alice hey, how are you?           # private message to Alice
> /users                                 # see who is online
> /quit                                  # disconnect

Running on Different Machines (Same Wi-Fi)

To chat across two different computers on the same network:

  1. Find the server machine's local IP address:
    ipconfig     # Windows
    ifconfig     # Mac/Linux
  2. In Client.java, change SERVER_ADDRESS from "localhost" to the server's IP (e.g., "192.168.1.5").
  3. Recompile and run the client on the other machine.

✨ Features

Feature Description
Global Chat Any text message is broadcast to all connected users
Private Messaging /msg [username] [message] sends a direct message to one user
Active Users List /users displays everyone currently online
Unique Usernames Server enforces unique names — no duplicates allowed
Join/Leave Notifications Everyone is notified when a user joins or leaves
Graceful Disconnect /quit safely removes the user and closes the connection
Crash-Safe If a client's terminal is closed abruptly, the server handles it without crashing

🧠 What I Learned

  • How TCP sockets establish and maintain reliable connections between machines.
  • The importance of multithreading in server design — without it, only one user can connect at a time.
  • Why thread safety matters: using ConcurrentHashMap to prevent data corruption when multiple threads modify shared state.
  • How to design a simple application-layer protocol with defined message formats and commands.
  • The difference between blocking I/O (used here) and non-blocking I/O (Java NIO), and the trade-offs of each.

🔮 Future Improvements

  • Add chat rooms / channels (like IRC's #general, #random)
  • Message timestamps
  • File sharing between users
  • Encryption using Java's javax.net.ssl.SSLSocket for secure communication
  • A graphical UI using JavaFX

🛠️ Built With

  • Language: Java (JDK 8+)
  • Networking: java.net.Socket, java.net.ServerSocket
  • Concurrency: java.util.concurrent.ExecutorService, ConcurrentHashMap
  • No external libraries or frameworks

📜 License

This project was built as a Computer Networks academic project. Feel free to use it as a reference or learning resource.

About

A multithreaded terminal-based chat server built from scratch in Java using TCP Sockets, featuring real-time messaging, private DMs, and concurrent connection handling — no external libraries. C

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages