A robust multi-client TCP chat application with server-client architecture implemented in C. Features concurrent client handling, username management, message broadcasting, and graceful disconnect handling.
- Concurrent Client Handling: Server supports up to 100 simultaneous clients using POSIX threads
- Username Management: Unique username registration with duplicate detection
- Message Broadcasting: Real-time message delivery to all connected clients
- User Notifications: Join/leave notifications for all users
- Graceful Shutdown: Clean disconnect handling for both clients and server
- Error Handling: Comprehensive error handling throughout the codebase
- POSIX Sockets: Standard TCP/IP communication using POSIX sockets API
- Thread-Safe: Mutex-protected shared resources
- Listens for incoming TCP connections on a configurable port (default: 8888)
- Spawns a new thread for each connected client
- Maintains a thread-safe list of active clients
- Broadcasts messages to all connected clients
- Handles user registration, message routing, and disconnections
- Supports graceful shutdown via SIGINT/SIGTERM signals
- Connects to the server using TCP
- Registers a username upon connection
- Runs two threads: one for sending messages, one for receiving
- Displays incoming messages and notifications in real-time
- Supports graceful disconnect via
/quitcommand or Ctrl+C
- Fixed-size message structure (547 bytes per message)
- 9 message types for different operations
- See PROTOCOL.md for detailed protocol specification
- GCC compiler with C11 support
- POSIX threads library (pthread)
- Linux/Unix operating system
makeThis will compile both server and client executables.
To build only the server:
make serverTo build only the client:
make clientTo clean build artifacts:
make clean./server [port]Examples:
./server # Starts server on default port 8888
./server 9000 # Starts server on port 9000Output:
[Server] Chat server started on port 8888
[Server] Waiting for connections...
./client [server_ip] [port]Examples:
./client # Connects to 127.0.0.1:8888
./client 192.168.1.100 # Connects to 192.168.1.100:8888
./client 127.0.0.1 9000 # Connects to 127.0.0.1:9000Interactive Session:
=== TCP Chat Client ===
Enter your username: Alice
Connecting to 127.0.0.1:8888...
Connected to server!
[Server] Welcome to the chat, Alice!
You can now start chatting!
Type your messages and press Enter to send.
Press Ctrl+C to quit.
> Hello everyone!
[Alice] Hello everyone!
*** Bob has joined the chat ***
>
- Send message: Type any text and press Enter
- Quit: Type
/quitor press Ctrl+C - Help: Messages starting with
/are reserved for commands
-
Start the server:
./server
-
Start first client in a new terminal:
./client
Enter username:
Alice -
Start second client in another terminal:
./client
Enter username:
Bob -
Verify:
- Alice should see "Bob has joined the chat"
- Both clients can send and receive messages
- Messages are broadcast to all clients
- Server logs all activities
-
Test disconnect:
- Type
/quitin Bob's client - Alice should see "Bob has left the chat"
- Server logs the disconnect
- Type
-
Test server shutdown:
- Press Ctrl+C in the server terminal
- All clients should receive shutdown notification
See PROTOCOL.md for complete protocol documentation including:
- Message structure and types
- Connection flow diagrams
- Error handling
- Security considerations
- Performance characteristics
The implementation includes comprehensive error handling for:
- Socket creation and connection failures
- Memory allocation failures
- Thread creation failures
- Network I/O errors
- Invalid input validation
- Graceful handling of unexpected disconnections
- Maximum 100 concurrent clients
- Username length limited to 31 characters
- Message length limited to 511 characters
- No message encryption (plain text)
- No persistent message storage
- No authentication beyond username
- TLS/SSL encryption for secure communication
- Password-based authentication
- Private messaging between users
- Message history and persistence
- File transfer support
- Rate limiting and spam protection
- IPv6 support
- epoll-based event-driven I/O for better scalability
This project is licensed under the terms of the LICENSE file in this repository.
- Server uses one thread per client model
- Main thread accepts connections
- Each client thread handles send/receive for one client
- Mutexes protect shared client list
clients_mutex: Protects the global clients arraysend_mutex: Protects client socket writes- Detached threads for automatic cleanup
- SIGINT/SIGTERM: Graceful shutdown
- SIGPIPE: Ignored to prevent crashes on broken pipes
- Dynamic allocation for client structures
- Proper cleanup on disconnect
- No memory leaks in normal operation