A multithreaded FTP client-server application built with C++ using TCP sockets and a custom thread pool. Supports multiple concurrent clients, asynchronous command execution, in-flight task termination, and chunked file transfer with a length-prefixed message protocol.
- Concurrent client support: Server handles multiple clients simultaneously using a thread pool, with each client getting its own
ClientHandler - Custom message protocol: Length-prefixed messages in the format
$<serverID>#<clientID>#<length>#<message>enable multiplexing multiple operations over a single connection - Asynchronous commands: Append
&to any command to run it in the background (e.g.,get largefile.txt &) - Task termination: Running tasks can be terminated by ID with the
terminatecommand, cancelling in-progress file transfers cleanly - Chunked file transfer: Files are transferred in configurable chunks with acknowledgment after each chunk
- Dual-socket architecture: Separate normal and terminate sockets per client for out-of-band task cancellation
- Thread pool: Custom thread pool implementation with graceful shutdown support
myftpserver-- Listens on two ports (normal + terminate). For each connecting client, creates aClientHandlerthat runs in the thread pool. Receives protocol-formatted messages, parses them, and dispatches FTP commands to worker threads. Each command gets a uniqueserverIDfor tracking.myftp-- Connects to both server ports. Provides an interactivemyftp>prompt. Uses aTaskHandlerwith a background receive thread to handle asynchronous server responses. Commands can be run synchronously or asynchronously (with&).
make # builds both myftpserver and myftp
make clean # removes binaries and object filesRequires a C++ compiler with C++20 support and pthreads.
-
Start the server with two port numbers (normal and terminate):
./myftpserver 8000 8001
-
In another terminal, connect a client:
./myftp 8000 8001
-
Available commands at the
myftp>prompt:get <filename>-- Download a file from the serverput <filename>-- Upload a file to the serverdelete <filename>-- Delete a file on the serverls-- List files in the server's current directorycd <directory>-- Change the server's working directorymkdir <directory>-- Create a directory on the serverpwd-- Print the server's working directoryterminate <task_id>-- Cancel a running task by its IDquit-- Disconnect from the server
-
Append
&to run a command asynchronously:myftp> get largefile.txt & myftp> put another.txt &
The server IP is defined as a preprocessor macro at the top of each source file. Change SERVER_IP before compiling to match your network setup:
#define SERVER_IP "127.0.0.1"