A concurrent TCP server for managing an employee database with a custom binary protocol. Implements stateful packet buffering and finite state machine for robust network communication.
- Concurrent multi-client support - Handle up to 10 simultaneous connections using
poll() - Stateful packet buffering - Handles TCP packet fragmentation with automatic reassembly
- Protocol handshake - Version negotiation with client validation
- Timeout detection - 5-second timeout for stalled partial receives
- Custom binary format - Network byte order for cross-platform compatibility
- CRUD operations - Create, list, add, and delete employee records
- Interactive client mode - Shell-like interface for database operations
- Finite state machine with 3 states:
S_NEW→S_CONNECTED→S_DISCONNECTED - Partial packet accumulation in per-client buffers
- Automatic cleanup of timed-out connections
- Binary database file with header validation
- TCP connection with protocol handshake (MSG_HELLO)
- Interactive mode for multiple operations
- Single-command mode for scripting
- Network byte order conversion for all requests
gcccompilermake- Linux/Unix environment (uses POSIX sockets)
make clean && makeThis creates two executables:
bin/dbview- The database serverbin/client- The client application
Create a new database and start the server:
./bin/dbview -f employees.db -nOpen an existing database:
./bin/dbview -f employees.dbThe server listens on port 5555 by default.
Interactive mode (recommended):
./bin/client -c 127.0.0.1 -iThis opens an interactive shell:
> list
Number of employees: 2
name: John Doe, address: 123 Main St, hours: 40
name: Jane Smith, address: 456 Oak Ave, hours: 35
> add Alice Johnson,789 Elm St,40
Added Alice Johnson, address: 789 Elm St
> del Alice Johnson
Deleting employee - Alice Johnson
> list
...
Single command mode (for scripting):
./bin/client -c 127.0.0.1 -l # List employees| Command | Format | Example |
|---|---|---|
list |
list |
Lists all employees |
add |
add name,address,hours |
add John Doe,123 Main St,40 |
del |
del name |
del John Doe |
All multi-byte integers stored in network byte order (big-endian).
| Field | Type | Size | Description |
|---|---|---|---|
| Magic | uint32_t | 4 | Magic number for file identification |
| Version | uint16_t | 2 | Database format version |
| Count | uint16_t | 2 | Number of employee records |
| Filesize | uint32_t | 4 | Total file size in bytes |
| Field | Type | Size | Description |
|---|---|---|---|
| Name | char[] | 256 | Employee name |
| Address | char[] | 256 | Employee address |
| Hours | uint32_t | 4 | Hours worked (network order) |
typedef struct {
cmd_type_e cmd; // Command type (4 bytes, network order)
uint32_t len; // Data length (4 bytes, network order)
char data[512]; // Command payload
} request_t;- Client → Server:
MSG_HELLOwith protocol version - Server → Client:
MSG_HELLOresponse (handshake accepted) - Client → Server: Command requests (LIST/ADD/DELETE)
- Server → Client: Response data
Connection rejected if:
- First message is not
MSG_HELLO - Protocol version mismatch
- Partial packet times out after 5 seconds
The server accumulates bytes using bytes_received tracking:
recv(fd, buffer + bytes_received, sizeof(request_t) - bytes_received, 0)Defers byte order conversion until full packet received to avoid operating on incomplete data.
- S_NEW: New connection - expects MSG_HELLO handshake
- S_CONNECTED: Authenticated client - processes commands
- S_DISCONNECTED: Connection closed or failed validation
Uses poll() for I/O multiplexing with per-client state tracking. Supports up to 10 concurrent clients (configurable via MAX_CLIENTS).
.
├── include/ # Header files
│ ├── common.h # Shared types and constants
│ ├── server.h # Server interface
│ ├── client.h # Client interface
│ ├── parse.h # Database operations
│ └── file.h # File I/O
├── src/ # Source files
│ ├── server.c # TCP server with FSM
│ ├── client.c # TCP client
│ ├── main.c # Server entry point
│ ├── parse.c # CRUD operations
│ └── file.c # Database file handling
├── bin/ # Compiled executables
├── obj/ # Object files
└── Makefile # Build configuration
- Maximum 10 concurrent connections
- Employee name/address limited to 256 characters
- No authentication/encryption (TCP plaintext)
- Single-threaded server (uses poll, not threads)
- No Windows support (POSIX sockets only)
gcc -Wall -Wextra -Wunused -g -IincludeStart server in one terminal:
./bin/dbview -f test.db -nRun multiple clients in separate terminals:
./bin/client -c 127.0.0.1 -iTest partial packet handling by artificially slowing network or using tools like tc (traffic control).
This project was developed as part of my learning path at lowlevel.academy.
Generative AI was used to assist with debugging, documentation generation, and code review. All implementation decisions, architecture choices, and final code were written and validated by me.
This project is licensed under the GPL-3.0 license - see LICENSE for details.