A peer-to-peer file sharing application written in Rust.
The system has two parts:
- Daemon — runs locally, discovers peers via multicast, shares files, and serves file chunks to other peers.
- CLI (
p2p-cli) — talks to the daemon over TCP to share, scan, list, download, and view status.
Downloading is chunk-based: a file is split into fixed-size blocks (e.g.
CHUNK_SIZE = 4096). The client may fetch different blocks from multiple seeders in parallel (torrent-style).
cargo build --release./target/release/p2p-daemonThe daemon will:
- determine its LAN IP and join the multicast group;
- listen for scan requests and reply with its shared files;
- serve chunked uploads to downloading peers.
./target/release/p2p-cli <command> [args]Share a file with the LAN.
p2p-cli share ./myfile.txtBroadcast a scan request to discover files shared by peers.
p2p-cli scanList files currently available to download (after a scan).
p2p-cli lsDownload by file name.
-f, --file <NAME>— file name to download (required)-o, --out <OUT_DIR>— optional output directory (defaults to current dir)-w, --wait— block the CLI until the download completes
# Download into current directory
p2p-cli download -f myfile.txt
# Download into ./downloads and wait until finished
p2p-cli download -f myfile.txt -o ./downloads -wShow current status (shared files, transfers, downloads).
p2p-cli status- Discovery: peers use UDP multicast to announce/scan available files.
- Control channel: the CLI talks to the local daemon over TCP; daemons also use TCP to exchange file lists and to transfer chunks.
- Chunking: files are split into blocks of size
CHUNK_SIZE. The last block may be smaller. - Parallelism: when multiple seeders report the same file size, the downloader splits the block ranges among them and fetches ranges concurrently.
- Integrity: ranges are written at their offsets. If any range fails and cannot be recovered, the partial file is removed.
- Logging: verbosity is controlled by the project’s
Logger(see code). Typical setups use an env var or config flag to choose level.
- Network addresses, ports, and
CHUNK_SIZEare defined in project config (p2p_config). - Platform specifics are handled via
#[cfg(windows)]/#[cfg(unix)]where needed.
# Build
cargo build
# Run daemon (in one terminal)
./target/debug/p2p-daemon
# Use CLI (in another terminal)
./target/debug/p2p-cli scan
./target/debug/p2p-cli lsRun tests:
cargo testRun continuous client interactions in a separate terminal to keep the daemon busy during profiling:
while true; do
./target/release/p2p-cli scan
./target/release/p2p-cli download -f my-message.txt
doneFirst, get the daemon's PID:
pidof p2p-daemon
# example output:
21224Then run perf against that PID:
sudo perf record -F 999 -p 21224 --call-graph dwarf -- sleep 30You can abort the client activity loop after profiling completes.
sudo perf reportIn your Cargo.toml, add:
[profile.release]
debug = true # for profilingecho -1 | sudo tee /proc/sys/kernel/perf_event_paranoid
echo 0 | sudo tee /proc/sys/kernel/kptr_restrictcargo flamegraph --release --bin p2p-daemonAfter the process finishes (via Ctrl+C or normal exit):
xdg-open flamegraph.svg
# or
firefox flamegraph.svgThe -F option in perf record controls the sampling frequency (samples per second per thread).
-
Higher frequency (e.g.,
-F 999) gives more precise profiles, especially for short-lived or very fast functions, but:- Increases overhead on the CPU.
- Produces larger
perf.datafiles. - Can distort timings if the target process is sensitive to profiling load.
-
Lower frequency (e.g.,
-F 99or-F 199) is usually sufficient for longer profiling sessions or when looking for major hotspots.
Guideline:
- Use
-F 99for general, long-running profiling. - Use
-F 199or-F 499for medium-length sessions when more detail is needed. - Reserve
-F 999for short (10–30s) sessions focusing on high-precision, CPU-bound code.
Example:
# Safe, general-purpose sampling
sudo perf record -F 99 -p <PID> --call-graph dwarf -- sleep 30
# High-precision sampling for a short period
sudo perf record -F 999 -p <PID> --call-graph dwarf -- sleep 15- No persistent resume of partially downloaded files after daemon restart.
- No per-chunk hashing yet (peer size agreement is used to filter mismatches).
- Basic error handling/logging; refine retries/backoff and diagnostics.