From ebdda992b8252f935986b8913665d20b61ff1ab3 Mon Sep 17 00:00:00 2001 From: Aleksandr Kovalko Date: Sat, 2 May 2026 03:15:47 +0200 Subject: [PATCH] Make inter-packet delay configurable via --delay-ms --- README.md | 1 + src/Config.cpp | 7 ++++--- src/Config.hpp | 2 ++ src/Main.cpp | 7 +++++++ src/Receiver.cpp | 2 +- src/Sender.cpp | 2 +- tests/e2e.sh | 12 ++++++++---- 7 files changed, 24 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6b1bc73..6ef0549 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ If your platform isn't covered, see [Building from Source](#building-from-source | `--bind-port` | `33333` | 1..65535 | Local port to bind on | | `--mtu` | `1500` | 64..65507 | Max packet size in bytes | | `--ttl` | `15` | > 0 | Seconds of silence before giving up | +| `--delay-ms` | `20` | ≥ 0 | Pause between successive packets (use `0` for loopback / tests) | | `-h, --help` | — | — | Print help | | `--version` | — | — | Print version | diff --git a/src/Config.cpp b/src/Config.cpp index b8f47a1..0f316d3 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -2,9 +2,10 @@ std::string fileName; -int mtu = 0; -int ttl = 0; -int ttl_max = 0; +int mtu = 0; +int ttl = 0; +int ttl_max = 0; +int delay_ms = 0; SOCKET _socket; diff --git a/src/Config.hpp b/src/Config.hpp index 06273ed..67d5a88 100644 --- a/src/Config.hpp +++ b/src/Config.hpp @@ -13,6 +13,8 @@ extern int mtu; // Max packet size to send and receive extern int ttl; // Current wait time for new packages before shutting down extern int ttl_max; // Maximum wait time for new packages before shutting down +extern int delay_ms; // Inter-packet pause when blasting parts / RESENDs + extern SOCKET _socket; extern SOCKADDR_IN server_address; diff --git a/src/Main.cpp b/src/Main.cpp index dd60f69..3532fe5 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -38,6 +38,7 @@ int main(int argc, char* argv[]) { ("bind-port", "Local port to bind on", cxxopts::value()->default_value("33333")) ("mtu", "MTU packet", cxxopts::value()->default_value("1500")) ("ttl", "Time to live", cxxopts::value()->default_value("15")) + ("delay-ms", "Delay between successive packets, ms", cxxopts::value()->default_value("20")) ("h,help", "Print help") ("version", "Print version"); @@ -64,6 +65,7 @@ int main(int argc, char* argv[]) { int parsed_ttl = result["ttl"].as(); int parsed_port = result["port"].as(); int parsed_bind_port = result["bind-port"].as(); + int parsed_delay_ms = result["delay-ms"].as(); if (parsed_mtu < 64 || parsed_mtu > 65507) { std::cerr << "Error: --mtu must be between 64 and 65507" << std::endl; @@ -81,6 +83,10 @@ int main(int argc, char* argv[]) { std::cerr << "Error: --bind-port must be between 1 and 65535" << std::endl; return 1; } + if (parsed_delay_ms < 0) { + std::cerr << "Error: --delay-ms must be 0 or greater" << std::endl; + return 1; + } const std::string type = result["type"].as(); if (type != "sender" && type != "receiver") { @@ -102,6 +108,7 @@ int main(int argc, char* argv[]) { mtu = parsed_mtu; ttl = parsed_ttl; ttl_max = parsed_ttl; + delay_ms = parsed_delay_ms; fileName = result["file"].as(); _socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); diff --git a/src/Receiver.cpp b/src/Receiver.cpp index 1034bf8..4203015 100644 --- a/src/Receiver.cpp +++ b/src/Receiver.cpp @@ -59,7 +59,7 @@ void checkParts() { sendto(_socket, buffer, 10, 0, reinterpret_cast(&broadcast_address), sizeof(broadcast_address)); std::cout << "Request part of file with index " << index << std::endl; - std::this_thread::sleep_for(20ms); + if (delay_ms > 0) std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); } SOCKADDR_IN sender_address; diff --git a/src/Sender.cpp b/src/Sender.cpp index f405921..95de71c 100644 --- a/src/Sender.cpp +++ b/src/Sender.cpp @@ -113,7 +113,7 @@ void run() { for (size_t part_index = 0; part_index < total_parts; ++part_index) { sent_part.insert({ part_index, 0 }); sendPart(part_index); - std::this_thread::sleep_for(20ms); + if (delay_ms > 0) std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms)); } snprintf(buffer, 7, "FINISH"); diff --git a/tests/e2e.sh b/tests/e2e.sh index a45c9cc..03e2f3b 100755 --- a/tests/e2e.sh +++ b/tests/e2e.sh @@ -38,9 +38,12 @@ run_test() { dd if=/dev/urandom of="$src" bs=1024 count="$size_kb" status=none # Receiver listens on $recv_port, sends RESEND back to $send_port (sender's bind). + # --delay-ms 0 removes the inter-packet pause that the protocol uses on real + # LANs to avoid overrunning receivers; on loopback it just slows tests down. echo "==> [$label] starting receiver (bind=$recv_port, target=$send_port)" "$BINARY" --type receiver --file "$dst" --broadcast 127.0.0.1 \ --bind-port "$recv_port" --port "$send_port" --ttl "$recv_ttl" \ + --delay-ms 0 \ > "$recv_log" 2>&1 & local recv_pid=$! @@ -51,6 +54,7 @@ run_test() { echo "==> [$label] starting sender (bind=$send_port, target=$recv_port)" if ! "$BINARY" --type sender --file "$src" --broadcast 127.0.0.1 \ --bind-port "$send_port" --port "$recv_port" --ttl "$send_ttl" \ + --delay-ms 0 \ > "$send_log" 2>&1; then echo "FAIL: [$label] sender exited non-zero" echo "--- sender log:"; cat "$send_log" @@ -90,11 +94,11 @@ run_test() { # Args: label, size_kb, recv_bind_port, send_bind_port, recv_ttl, send_ttl # -# Small file: 50 KiB -> ~35 parts at default MTU 1500, ~0.7s transfer. -run_test "small" 50 33401 33402 5 3 +# Small file: 50 KiB -> ~35 parts at default MTU 1500. +run_test "small" 50 33401 33402 3 1 -# Large file: 2 MiB -> ~1400 parts at default MTU 1500, ~28s transfer. -run_test "large" 2048 33403 33404 60 30 +# Large file: 2 MiB -> ~1400 parts at default MTU 1500. +run_test "large" 2048 33403 33404 3 1 echo echo "All E2E tests passed."