Bidirectional reliable transport over UDP, built from scratch in C. Verified to transfer files up to 2MB with complete data integrity under poor network conditions (5% packet loss and 100% packet reordering.)
Packet format — 8-byte fixed header includes sequence number, ACK number, flags, and payload length. Max payload length is 1012 bytes.
No handshake — The server learns the client's address via a mandatory "packet 0" sent on startup. Instead of ensuring liveness with a handshake, we simply retransmit packet 0 if lost; instead of exchanging transfer parameters, we hard-code starting sequence numbers for each side. This trades robustness for simplicity.
Reliability — On the sender side, we track in-flight packets in a linked list and use unbounded Go-Back-N retransmission with timeout-driven batch resend: when the RTO (1 second) expires for the earliest in-flight packet, all in-flight packets are retransmitted.
Fast retransmit — On three consecutive duplicate ACKs, retransmission kicks in immediately. Expected recovery time drops from 1 second to 3 RTTs. For bidrectional transfer (2MB files both ways) under 5% packet drop and full packet reordering, fast retransmit cut transfer latency by 34x (38s to 1.1s).
In-order delivery — A sorted receiver-side buffer (linked list) holds packets that arrive out-of-order. Once an incoming packet fills the gap, the buffer drains contiguous packets to stdout.
ACKs are not ACK'd — Pure-ACK packets are flagged and do not trigger ACK replies, preventing eternal ACK spirals.
Graceful teardown — Once stdin hits EOF, a FIN-flagged packet is sent to the peer; each half of the connection closes independently. The process exits as soon as both FINs are acknowledged, rather than waiting to be killed externally.
cd src && make
Both peers send and receive simultaneously. Each reads from stdin and writes received data to stdout — run them in separate terminals, and use shell redirection to feed a file in and capture output:
Terminal 1
./server <port> < file_to_send > received_fileTerminal 2
./client <host> <port> < file_to_send > received_fileA Docker-based test harness with a configurable proxy (drop rate, reorder rate) is included:
./helper proxy 0.05 1.0 # start proxy manually (5% drop, 100% reorder)