What does the word "retransmit" actually mean? I thought I knew. I'd taken the networking class. I'd read the chapter. I could draw the slow-start curve on a whiteboard. Then I tried to write it and discovered I had no idea.
This is a series about rebuilding TCP from scratch in Java, and the parts of it I only understood after the code actually ran.
What I built
LEAP (Loss-aware End-to-end Acknowledged Protocol) is a TCP-style reliable transport I built from scratch on top of UDP. About 1,900 lines of Java. It has sequence numbers, cumulative ACKs, a sliding window, fast retransmit on three duplicate ACKs, adaptive RTO in the style of RFC 6298, slow start and AIMD congestion control with an ssthresh floor, and end-to-end SHA-256 integrity verification on every transfer.
There's a CLI:
./bin/leap receive --port 4040 --output /tmp/in
./bin/leap send myfile.bin --to localhost:4040
And a benchmark harness that sweeps file size × loss rate × trial across LEAP and TCP.
I built this over about three weeks in March 2026, while doing my MS in CS at USC. Everything lives at github.com/bhaveshGhanchi/leap, including the protocol, CLI, benchmark harness, and plotting scripts. Each post in this series points at specific files and line numbers in that repo.
Why I bothered
A few reasons.
The first is that reading about TCP is not the same as implementing it. Stevens' TCP/IP Illustrated has roughly 200 pages on TCP. They're great pages. They didn't prepare me for writing the retransmission timer loop. The textbook says "the sender retransmits if it doesn't receive an ACK within RTO." The code has to actually handle four cases at once: the original ACK arrives normally, the ACK is late but arrives during retransmission, the ACK never arrives and you keep retransmitting, and the path is just slow rather than lossy and your RTO needs to grow without spiraling. The textbook compresses all of that into one sentence. The code can't.
The second is congestion control. Most engineers can sketch the cwnd graph: slow start ramp, then sawtooth. Far fewer can tell you what a duplicate ACK actually is at a code level, or why three of them is the magic number, or what ssthresh = max(cwnd/2, 4) does to a flow that's just hit its first loss. I couldn't have told you any of these before this project. I can now, because I had to write each one and watch what happened when I got it wrong. Which I did. Several times.
The third is measurement. Anyone can benchmark a happy path: localhost, no loss, "look how fast my code goes." The interesting question is what TCP-like protocols do at 5% loss, 10% loss, 20% loss. I wanted to see those curves with code I'd written, where I knew exactly which packet was retransmitted, why, and what the cwnd was at the moment the loss happened.
I also wanted to measure honestly, which turned out to be much harder than the implementation. Chapter 6 of this series is about how I built three different ways of simulating packet loss, two of which silently lie, and how I figured out which two.
None of this is novel. TCP Tahoe is from 1988. Van Jacobson and Mike Karels figured out the hard parts before I was born. I'm not trying to push the state of reliable transport forward. I'm trying to understand it.
Who this series is for
- You've taken a networking class and want to see the textbook ideas as code that compiles.
- You use TCP every day in production and want to know what's inside the syscall.
- You're curious what "congestion window" means at line-of-code level, not at whiteboard level.
- You like reading code with measurements attached, and writeups that admit when things didn't work.
This isn't for people looking for a production reliable-UDP library. Use QUIC. There are excellent open-source implementations like msquic, quiche, and quic-go. They have encryption, multiplexing, NAT traversal, modern congestion control, and a decade of production hardening. LEAP has none of those. It's a project I built to understand TCP.
What's coming
Six posts:
- Why bother when TCP exists? (this post)
- Sequence numbers, ACKs, and the simplest reliable protocol that works
- Sliding window: the trick that makes TCP fast
- Retransmission timers: why RTO is the hardest part
- Congestion control: TCP's politeness algorithm
- Measuring it honestly: three ways to fake packet loss, two of which lie
Each post pulls from a specific part of the LEAP repo. By the end, you'll have seen enough code to implement your own version, and enough about measurement methodology to be skeptical of anyone else's.
What I'm not claiming
LEAP is not faster than TCP. TCP wins on every benchmark in this series at every loss rate, which is fine. TCP has been optimized for thirty years and runs in the kernel. LEAP runs in userspace Java.
It's not novel either. TCP Tahoe is 1988. The interesting thing is what I learned by writing it.
It's also not production-ready. Single sender, single receiver, one file per session, no encryption, no NAT traversal, localhost-tested only. Don't put it on the internet.
How to read along
The repo is at github.com/bhaveshGhanchi/leap. The README has the full architecture: packet format, protocol design, benchmark methodology, limitations. If you read code, the entire implementation is roughly 1,900 lines of Java; you can read it in an evening before starting this series. If you'd rather read prose, this series is the slower walkthrough, with the bugs and dead ends included.
Up next
Chapter 2 is about the simplest reliable protocol that works: stop-and-wait. It works. It's also almost unusable on any real network. We'll see how unusable, and then start fixing it.
Top comments (0)