Skip to content
adarsh0707-kumarPublic

About

Real-time multi-client chat application built with C++ using POSIX sockets

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

18 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chat Application — C++ TCP Sockets

A real-time multi-client chat system built from scratch with POSIX TCP sockets, C++ threads, and a small text-based protocol.

This project is a low-level networking exercise focused on the path between a TCP connection and a usable real-time messaging system.

The server accepts multiple clients, assigns unique usernames, routes broadcast/private messages, and protects shared client state with a mutex. Each client uses a dedicated receive thread so incoming messages can be displayed while the user is typing.

Status: Working educational prototype
Focus: C++ networking, TCP sockets, concurrency, and protocol design
Environment: Linux/Unix with POSIX socket support


What it implements

  • Multi-client TCP server
  • Broadcast messaging
  • Private messages with /msg <username> <message>
  • Unique username validation
  • Join/leave notifications
  • /help command
  • exit client command
  • HH:MM timestamps
  • Concurrent client handling with one server thread per connection
  • Client receive thread for asynchronous incoming messages
  • Mutex-protected shared client registry
  • Basic handling of connection/disconnection failures

Architecture

                         TCP
              ┌─────────────────────┐
              │                     │
        ┌─────▼─────┐         ┌─────▼─────┐
        │  Client 1 │         │  Client 2 │
        │ send/input│         │ send/input│
        │ receive   │         │ receive   │
        │  thread   │         │  thread   │
        └─────┬─────┘         └─────┬─────┘
              │                     │
              └──────────┬──────────┘
                         ▼
                ┌─────────────────┐
                │  TCP Chat       │
                │     Server      │
                ├─────────────────┤
                │ accept()        │
                │ thread/client   │
                │ username map    │
                │ broadcast       │
                │ private routing │
                └─────────────────┘

Server

server/src/server.cpp:

  1. Creates a TCP socket.
  2. Binds to port 9000.
  3. Listens for incoming connections.
  4. Accepts clients and creates a detached thread per client.
  5. Tracks sockets and usernames in a shared map.
  6. Broadcasts normal messages to other connected clients.
  7. Routes /msg messages to a matching username.
  8. Announces joins and departures.

Client

client/client.cpp:

  • Connects to 127.0.0.1:9000.
  • Sends the chosen username.
  • Starts a receive thread for server messages.
  • Reads user input from the main thread.
  • Sends messages over TCP.
  • Shuts down the socket when exit is entered.

Protocol

The current protocol is intentionally minimal: raw text over TCP.

Client → server

Initial connection:

<username>

Normal message:

hello everyone

Private message:

/msg Adarsh hello

Help:

/help

The server generates timestamped display messages such as:

[14:32] Adarsh: hello everyone
[14:33] [PRIVATE] Rahul: hello

This is not a framed or versioned wire protocol. TCP message boundaries are therefore not explicitly defined by the application.


Build

Requirements

  • Linux/Unix environment
  • g++
  • C++17
  • POSIX sockets
  • GNU Make
  • pthread support

Build the server

cd server
make

Build the client

In another terminal:

cd client
make

Both Makefiles compile with C++17, warnings enabled, and pthread support.


Run

1. Start the server

From the repository root:

./server/server

The server listens on:

0.0.0.0:9000

2. Start a client

./client/client

Enter a unique username when prompted.

3. Start additional clients

Open additional terminals and run:

./client/client

Use different usernames to test broadcast and private messaging.


Commands

Command Purpose
/msg <username> <message> Send a private message
/help Show available server commands
exit Disconnect the client

Any other input is treated as a broadcast message.


Project structure

Chat-app/
├── server/
│   ├── include/
│   │   └── server.h
│   ├── src/
│   │   └── server.cpp
│   └── Makefile
├── client/
│   ├── include/
│   │   └── client.h
│   ├── client.cpp
│   └── Makefile
└── README.md

Concurrency model

The current implementation uses a deliberately simple threading model:

  • Server: one detached std::thread per connected client.
  • Shared state: std::map<int, std::string> protected by a std::mutex.
  • Client: one main input thread plus one receive thread.

This keeps the implementation easy to follow while exposing the important concurrency problem: multiple client handlers access the same connection registry.

It is not intended to be an optimal high-concurrency architecture.


Engineering trade-offs

Area Current design Consequence
I/O Blocking POSIX sockets Simple, but threads block on network operations
Server concurrency Thread per client Easy to reason about; thread count scales with connections
Protocol Raw text Simple, but no message framing/versioning
Client receive Dedicated thread Incoming messages can arrive asynchronously
Client registry Mutex + map Straightforward synchronization
Persistence None Messages disappear when the process stops
Authentication None Usernames are not identities
Encryption None Traffic is unencrypted

Limitations

This is a learning-focused networking prototype, not a production chat service.

Current limitations include:

  • No authentication or authorization.
  • No TLS/encryption.
  • No persistent message history.
  • No database.
  • No file/media transfer.
  • No rate limiting or abuse controls.
  • No message IDs or delivery acknowledgements.
  • No explicit application-level message framing.
  • No protocol versioning.
  • No graceful server shutdown path.
  • Thread-per-client architecture limits scalability compared with event-driven I/O.
  • No automated test suite or benchmark suite is currently provided.

These limitations are useful boundaries for future networking work rather than features the current implementation claims to provide.


Roadmap

  1. Define a length-prefixed or otherwise framed application protocol.
  2. Add structured message types and protocol versioning.
  3. Improve socket error handling and graceful server shutdown.
  4. Add connection lifecycle tests.
  5. Add integration tests with multiple clients.
  6. Add authentication and authorization.
  7. Add TLS.
  8. Add persistent message history.
  9. Measure concurrency and message-throughput limits.
  10. Evaluate epoll/non-blocking I/O for higher connection counts.

The most important next engineering step is message framing: TCP is a byte stream, so relying on individual read() calls as complete messages is not a robust protocol boundary.


Why this project matters

This project demonstrates hands-on work with:

  • TCP/IP sockets
  • POSIX networking APIs
  • concurrent C++ programming
  • synchronization with mutexes
  • connection lifecycle management
  • simple protocol design
  • client/server architecture

It complements larger backend and distributed-systems projects by showing the lower-level networking layer directly.


Author

Adarsh Kumar

C++ • Networking • Backend Systems • Systems Programming


License

MIT — see LICENSE.

About

Real-time multi-client chat application built with C++ using POSIX sockets

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages