This project is an advanced, multithreaded TCP chat server built in Java. It is designed using a modern, service-oriented architecture to demonstrate key software engineering principles such as Separation of Concerns, Concurrency Management, and Protocol-Based Communication.
The server is capable of handling multiple simultaneous clients, managing different chat rooms, and facilitating direct peer-to-peer file transfers, all through a sophisticated dual-port communication system.
- Key Features
- New in this Version
- System Architecture
- How It Works
- Communication Protocol
- Getting Started
- Future Improvements
- Contributors
- Service-Oriented Architecture: The application logic is decoupled into distinct services (
LoginService,ChatroomManager,DataTransferManager), making the system modular, scalable, and easy to maintain. - Efficient Concurrency with a Thread Pool: A
ThreadExecutorServicemanages a fixed pool of threads based on available CPU cores, ensuring the server can handle numerous clients without succumbing to the high overhead of thread-per-client models. - Dual-Port Communication System: The server intelligently separates traffic types for maximum efficiency:
- Control Port (5010): Handles lightweight, command-based traffic like logins, chat messages, and transfer negotiations.
- Data Port (5011): A dedicated, high-throughput channel used exclusively for streaming large files between clients.
- Stateful Session and Chat Room Management: The server maintains the state of authenticated users and chat room memberships, providing features like message history and broadcasting to specific groups.
- Secure and Negotiated File Transfers: A robust, multi-step handshake protocol allows users to request, accept, or reject file transfers before any data is sent, ensuring security and consent.
- Custom Logging Framework: Implemented a robust, event-driven logger that writes structured output to both the console and a persistent
server.logfile. This provides deep insight into server activity and makes debugging significantly easier. - Emoji Support: Users can now express themselves with emojis! The server supports both direct Unicode emojis and translates common text shortcuts (like
:)) into their graphical equivalents (😊).
The server is built on a layered architecture where each component has a single, well-defined responsibility.
-
Server.java(The Network Hub) 🗼- This is the application's entry point. It acts as the central network hub, creating two
ServerSocketinstances on two separate threads—one for the control port and one for the data port. Its sole responsibility is to listen for and accept new socket connections, after which it immediately delegates all further interaction to other components.
- This is the application's entry point. It acts as the central network hub, creating two
-
ServerHandler.java(The Client's Diplomat) 🤵- Each client connecting to the control port is assigned a dedicated
ServerHandlerinstance running in the thread pool. This class is the command router for a single client. It reads the raw string data sent by the client, parses it to identify a command (e.g.,LOGIN,SEND_MSG,WANT_TO_SEND_FILE), and then invokes the appropriate service to handle the logic. It maintains the client's authenticated state and current chat room.
- Each client connecting to the control port is assigned a dedicated
-
LoginService.java(The Bouncer) 🔑- This service is the authority on user identity and sessions. It manages user creation, validates login attempts, and tracks which users are currently active and connected. It prevents the same user from logging in multiple times, ensuring session integrity.
-
ClientManager.java(The Switchboard Operator) ☎️- This static class acts as a central registry for all active client control sockets. It holds a
ConcurrentHashMapmapping a unique client ID to its socket connection. This allows any part of the server to send a message to a specific client (unibroadcastMessage) or to all clients (broadcastMessage) without needing direct access to the socket objects.
- This static class acts as a central registry for all active client control sockets. It holds a
-
ChatroomManager.java(The Architect) 🗺️- This service manages the lifecycle of chat rooms. It creates a set of default rooms on server startup and provides methods for users to list available rooms and join them. It also tracks the membership of each room, which is crucial for targeted message broadcasting.
-
DataTransferManager.java(The Logistics Coordinator) 🚚- This is the core of the file transfer system. It manages the pairing of sender and receiver sockets on the data port. When a file transfer is accepted, both clients are instructed to connect to the data port. This manager waits for both connections, pairs them using a unique transfer ID, and then initiates a
relayFileStreamthat pipes the bytes directly from the sender'sInputStreamto the receiver'sOutputStream.
- This is the core of the file transfer system. It manages the pairing of sender and receiver sockets on the data port. When a file transfer is accepted, both clients are instructed to connect to the data port. This manager waits for both connections, pairs them using a unique transfer ID, and then initiates a
- Client: The user types a message in
ClientUI. The client formats this into a protocol string:SEND_MSG::...::Hello World :). - Server (Control Port): The
Serveraccepts the connection and the client's dedicatedServerHandlerreads the string. - Command Routing & Parsing: The
ServerHandleridentifies theSEND_MSGcommand and usesMessageProtocolto parse the string into aMessageModelobject. - Emoji Conversion: The server checks the message content for shortcuts like
:)and converts them to😊. - Broadcasting: The
ServerHandlergets the user's current chat room fromChatroomManagerand usesClientManager.unibroadcastMessage()to send the final, formatted message to all members of the room.
- Initiation (User A): User A sends a request:
WANT_TO_SEND_FILE::UserB::document.pdf::102400. - Mediation (Server): User A's
ServerHandlervalidates that User B is online and forwards the request:INCOMING_FILE::UserA::.... - Acceptance (User B): User B accepts, sending
ACCEPT_FILE::[transferId]back to the server. - Orchestration (DataTransferManager): The server sends commands to both clients (
START_FILE_TRANSFERandPROCEED_WITH_DOWNLOAD), telling them to connect to the data port (5011) with the uniquetransferId. - Data Connection & Relaying: Both clients connect to the data port. The
DataTransferManagerpairs their sockets and starts piping the file data directly from the sender to the receiver. The server acts as a pass-through, never saving the file to its own disk.
The server operates on a strict, delimiter-based protocol (::).
LOGIN::[username]LOGOUTLIST_ROOMSJOIN_ROOM::[chatroomId]SEND_MSG::[...details...]::[content]
WANT_TO_SEND_FILE::[recipientUsername]::[filename]::[fileSize]ACCEPT_FILE::[transferId]REJECT_FILE::[transferId]
- Java Development Kit (JDK) 11 or newer.
- Clone the Repository:
git clone [https://github.com/gabrielrx31/ChatServer.git](https://github.com/gabrielrx31/ChatServer.git)
- Navigate to the Source Directory:
cd ChatServer/src/main/java/ - Compile All Java Files:
This command compiles all necessary packages in the correct order.
javac common/models/*.java common/protocols/*.java Services/*.java server/utils/*.java server/core/*.java
- Run the Server:
Execute the main
Serverclass. It will start listeners on ports 5010 (control) and 5011 (data).java server.core.Server
- Compile the Client:
In a new terminal, navigate to the same
src/main/java/directory.javac client/ClientUI.java
- Run the Client:
You can run multiple instances of the client to simulate a multi-user environment. Follow the on-screen prompts to log in and interact.
java client.ClientUI
- Persistent Storage: Replace the in-memory
Datahandlerwith a database (like SQLite or PostgreSQL) to persist users, chat rooms, and message history. - Private Messaging: Implement a
PRIVATE_MSGcommand to allow one-to-one communication. - Encryption: Use
SSLServerSocketandSSLSocketto encrypt all communication. - GUI Client: Build a graphical user interface using a framework like JavaFX or Swing for a more user-friendly experience.
- Jon
- Lasse
- Gabriel