A multi-client terminal chat application built from scratch in C. Supports real-time messaging between multiple clients over TCP sockets using select() for I/O multiplexing.
Built as Project 14 of a systems programming curriculum, following projects covering memory allocators, file explorers, process monitors, text editors, and HTTP servers.
- Multi-client support — up to 50 simultaneous connections
- Real-time broadcast — messages delivered to all connected clients instantly
- Username system — every client identifies with a username on connect
- Join/leave notifications — all clients are notified when someone connects or disconnects
- Non-blocking I/O — single-process server using
select(), no threads or forking - Clean disconnect handling — server recovers gracefully when clients drop
xchat/
├── server.c # Server logic — select() loop, broadcast, client tracking
├── server_main.c # Server entry point
├── client.c # Client logic — select() on stdin + server socket
├── client_main.c # Client entry point
└── CMakeLists.txt # Build configuration
Two separate binaries:
xchat_server— runs on the host machine, manages all connectionsxchat_client— connects to the server, one instance per user
The server uses a single select() loop to monitor multiple file descriptors simultaneously — no threads, no forking.
socket() → bind() → listen()
while (1):
rebuild fd_set from all connected client fds + listening socket
select() — block until any fd has activity
if listening socket ready → accept() new client, read username, broadcast join notice
for each client fd:
if ready → read message, broadcast to all others
if disconnected → broadcast leave notice, remove from array
Client state is tracked in two parallel arrays:
int clients[MAX_CLIENTS]— file descriptors, initialized to -1char usernames[MAX_CLIENTS][256]— username per slot
The client also uses select() to watch two fds at once:
stdin(fd 0) — user typed something → send to serverserver_fd— server pushed a message → print it
This allows the client to receive messages from other users at any time, without blocking on input.
Newline-delimited plain text over TCP.
- First message after connect → username
- All subsequent messages → chat content
- Server prefixes messages:
[username]: message - Server sends system notices:
*** username has joined the chat ***
Requirements:
- GCC or Clang
- CMake 3.10+
- macOS or Linux
cmake -B build
cmake --build buildThis produces two executables in build/:
build/xchat_serverbuild/xchat_client
Terminal 1 — start the server:
./build/xchat_serverTerminal 2+ — connect clients:
./build/xchat_clientEach client is prompted for a username on connect. After that, type and hit Enter to send.
Example session:
Client 1 (david):
Enter username: david
*** alice has joined the chat ***
[alice]: yo what's good
hello from david
Client 2 (alice):
Enter username: alice
yo what's good
[david]: hello from david
Server terminal:
*** david has joined the chat ***
*** alice has joined the chat ***
[alice]: yo what's good
[david]: hello from david
| Concept | Where Used |
|---|---|
select() / fd_set | Server and client I/O multiplexing |
socket() / bind() / listen() / accept() | TCP server setup |
connect() | Client connection |
SO_REUSEADDR | Prevent "address already in use" on restart |
inet_pton() | Convert IP string to binary |
htons() | Host to network byte order |
| Parallel arrays | Track client fds and usernames together |
| Newline framing | Simple message protocol over TCP byte stream |
- No message history — new clients only see messages sent after they join
- No encryption — plain text over TCP
- Local network only by default — server binds to
INADDR_ANY, client connects to127.0.0.1 - Max 50 clients — defined by
MAX_CLIENTS
xchat is one project in a series building toward EduOS — a privacy-first, AI-native Linux-based OS for African schools. Offline. Adaptive. No tracking.
The systems programming skills built here — sockets, multiplexing, process management, memory allocation — are the foundation that OS will run on.
Okocha David — Full Stack Engineer & Systems Programming Student
Lagos, Nigeria
X: @davidokocha086