Overview
A client-server chat application developed as a first-semester university project. The application implements a multi-user chat system using Java socket programming, focusing on OOP design principles, concurrent communication, and network programming fundamentals.
How It Works
The application follows a classic client-server model. The server starts listening on a port,
and each new client that connects gets its own dedicated ClientHandler thread.
A ClientManager keeps track of all active connections and is responsible for
broadcasting messages: when one client sends a message, the manager forwards it to every
other connected client.
The client side runs as a separate application with a UI for sending and receiving messages,
and a network package that handles the socket connection to the server.
What I Built
- A multi-user chat server that handles concurrent client connections
- Message broadcasting: all connected users receive every message in real time
- A client application with a chat interface for sending and viewing messages
- Clean separation into
server,client, andcommonpackages
Technical Details
- ServerSocket / Socket: the server blocks on
accept()and spins up a new thread for every incoming connection - Multithreading: each
ClientHandlerruns on its own thread, so multiple users can chat simultaneously without blocking each other - ClientManager: maintains the list of active handlers and iterates over them to broadcast each incoming message
- Gradle: used as the build system to manage dependencies and run the application
- Organized into three packages:
server,client(with controller and network sub-packages), andcommon
What I Learned
This was my first real experience with network programming and concurrency. The hardest part was thinking about what happens when multiple threads try to access the same list of clients at the same time, and making sure messages don't get lost or sent to the wrong person.
- Java socket programming: how TCP connections work at the code level
- Multithreading and why thread safety matters in a shared-state system
- Designing a clean package structure for a multi-component application
- The difference between building something that works and building something that stays stable under concurrent load