A TCP client-server file sharing system built for CSC209 (Software Tools and Systems Programming) at the University of Toronto St. George, Winter 2026.
Multiple clients connect to a central server to list, upload, and download files. When a client uploads a file, all other connected clients receive a real-time broadcast notification. The server runs a single-threaded select() event loop — no threads, no fork() per client.
make # build both server and client (default port 4242)
make PORT=9000 # build with a custom default port
make clean # remove build artifacts./server <port>Example:
./server 4242The server creates a ./storage/ directory if it doesn't already exist, then begins accepting connections.
./client <server_ip> <port>- Same machine: use
localhostor127.0.0.1 - LAN: use the server machine's IP (
hostname -Ion Linux,ifconfigon macOS) - teach.cs: use the hostname directly (e.g.
teach.cs.toronto.edu)
./client 127.0.0.1 4242
./client teach.cs.toronto.edu 4242fileshare> list # list files on the server
fileshare> upload path/to/file # upload a local file
fileshare> download filename # download a file to the current directory
fileshare> help # show available commands
fileshare> quit # disconnect and exit
# Terminal 1
./server 4242
# Terminal 2
./client 127.0.0.1 4242
# Terminal 3
./client 127.0.0.1 4242When one client uploads a file, all others receive:
[notification] New file available: example.txt
| File | Role |
|---|---|
protocol.h |
Shared message types, constants, wire-format header |
network.c/h |
Socket setup, send_all/recv_all, send_message |
file_ops.c/h |
Storage directory init, file listing, filename validation |
client_state.c/h |
Per-client state machine, read/write buffers |
server.c |
Server entry point, select() loop, upload/download/broadcast logic |
client.c |
Client entry point, select() on stdin + socket, command parsing |
Messages use a 5-byte length-prefixed header over TCP:
[type : uint8_t (1 byte)][payload_length : uint32_t (4 bytes, network order)][payload]
| Message | Direction | Description |
|---|---|---|
MSG_REQ_LIST |
Client → Server | Request file list |
MSG_RES_LIST |
Server → Client | File list response |
MSG_REQ_UPLOAD |
Client → Server | Begin upload (filename + file size) |
MSG_RES_UPLOAD_OK |
Server → Client | Upload accepted |
MSG_REQ_DOWNLOAD |
Client → Server | Request a file download |
MSG_RES_DOWNLOAD |
Server → Client | Download starting (file size) |
MSG_NEW_FILE |
Server → Client | Broadcast: new file available |
MSG_DATA_CHUNK |
Either | Raw file data chunk (≤ 4096 bytes) |
MSG_DONE |
Either | End of file transfer |
MSG_ERR |
Server → Client | Error message |
- File list is truncated to 4095 bytes if the server has many files.
- Files are limited to ~4 GB due to
uint32_tsize fields in the protocol. - Downloaded files are saved to the client's current working directory using the server-side filename.