A multi-client chat server and client written in C++ using POSIX sockets, supporting kqueue(linux epoll). Features real-time messaging, file transfer, private messaging, and two server architectures.
- Multi-client support - Multiple users can connect simultaneously
- Real-time messaging - Instant message delivery to all connected clients
- Private messaging - Send direct messages to specific users
- File transfer - Send files to individual users or broadcast to all
- User presence - See who's online
- Colored output - Easy-to-read terminal interface with timestamps
- Two server architectures - Thread-per-client and event-driven (kqueue)
This project includes two server implementations to demonstrate different approaches:
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Thread 1│ │ Thread 2│ │ Thread 3│
│ Client 1│ │ Client 2│ │ Client 3│
└─────────┘ └─────────┘ └─────────┘
- Simple to understand
- One thread per connected client
- Best for < 1,000 concurrent users
- Uses mutex for thread safety
┌─────────────────────────────────┐
│ SINGLE THREAD │
│ kevent() monitors ALL sockets │
└─────────────────────────────────┘
- High performance
- Single thread handles all clients
- Scales to 10,000+ concurrent users
- Uses macOS kqueue (similar to Linux epoll)
- C++17 or later
- POSIX-compliant OS (macOS, Linux)
- pthread library
# Clone the repository
git clone https://github.com/yourusername/tcp-chat.git
cd tcp-chat
# Compile thread-per-client server
g++ -std=c++17 -o server main.cpp -pthread
# Compile event-driven server (macOS)
g++ -std=c++17 -o server_kqueue server_kqueue.cpp -pthread
# Compile client
g++ -std=c++17 -o client client.cpp -pthread# Option 1: Thread-per-client server
./server
# Option 2: Event-driven server (recommended for high load)
./server_kqueue./clientYou'll be prompted to enter a username, then you can start chatting.
| Command | Description |
|---|---|
/help |
Show all available commands |
/quit |
Disconnect and exit |
/clear |
Clear the terminal screen |
/users |
List all online users |
/msg <user> <message> |
Send a private message |
/sendfile <user> <filepath> |
Send a file to a user |
/sendfile all <filepath> |
Send a file to everyone |
/me <action> |
Send an action message |
| Command | Description |
|---|---|
/help |
Show all available commands |
/quit |
Shutdown the server |
/list |
List connected clients |
/stats |
Show server statistics (kqueue version) |
<message> |
Broadcast message to all clients |
Terminal 1 (Server):
$ ./server_kqueue
[System] Server started on port 54000
[System] Mode: Event-driven (kqueue)
[System] 'alice' joined the chat!
[System] 'bob' joined the chat!
[14:30:01] alice: Hello everyone!
[14:30:05] bob: Hey alice!
Terminal 2 (Alice):
$ ./client
Enter your username: alice
[System] Connected!
Hello everyone!
[14:30:01] You: Hello everyone!
[14:30:05] bob: Hey alice!
/msg bob secret message
[PM to bob] secret message
Terminal 3 (Bob):
$ ./client
Enter your username: bob
[System] Connected!
[14:30:01] alice: Hello everyone!
Hey alice!
[14:30:05] You: Hey alice!
[PM from alice]: secret message
Files are saved to a downloads/ folder in the current directory.
# Send to specific user
/sendfile bob photo.png
# Send to everyone
/sendfile all document.pdftcp-chat/
├── main.cpp # Thread-per-client server
├── server_kqueue.cpp # Event-driven server (kqueue)
├── client.cpp # Chat client
├── README.md # This file
├── .gitignore # Git ignore file
└── downloads/ # Received files (created automatically)
Messages use a simple text-based protocol with prefixes:
| Prefix | Format | Purpose |
|---|---|---|
FILE: |
FILE:recipient:filename:size:data |
File transfer |
MSG: |
MSG:recipient:message |
Private message |
USERS |
USERS |
Request user list |
std::mutexprotects the shared clients vectorstd::atomic<bool>for clean shutdown signalinglock_guardfor RAII-style locking
- Non-blocking sockets with
O_NONBLOCK kqueue()creates kernel event queuekevent()monitors multiple file descriptors- Single thread handles all I/O operations
SO_REUSEADDRenabled for quick server restarts
| Aspect | Thread-per-Client | Event-Driven (kqueue) |
|---|---|---|
| Threads | 1 per client | 1 total |
| Memory | Higher (thread stacks) | Lower |
| Complexity | Simpler | More complex |
| Scalability | ~1,000 clients | 10,000+ clients |
| Mutex needed | Yes | No |