LastByteSent = highest byte number the sender has pushed into the network.
LastByteAcked = highest byte number the receiver has acknowledged.
Why these two? The in-flight (unacknowledged) bytes are exactly those sent but not yet acked:
in-flight=LastByteSent−LastByteAcked
Step 2 — the receiver's promise.
When the receiver advertised rwnd, it guaranteed it had that much free room. So the sender must keep:
LastByteSent−LastByteAcked≤rwnd
Why this is exactly right: every in-flight byte will eventually land in the receive buffer. If in-flight bytes ≤ free space, the buffer can absorb all of them without overflow. Q.E.D. — the sliding-window rule is just "in-flight ≤ advertised free space."
Imagine you're pouring water into a friend's cup through a hose. Your friend drinks slowly. Every moment your friend shouts "I have THIS much space left in my cup!" You only pour that much, no more — so the cup never overflows. When the cup is full, your friend shouts "ZERO space!" and you stop pouring. You keep gently tapping the hose now and then to ask "any room yet?" When your friend drinks some and shouts "okay, room again!", you start pouring. That shouted number is the window, the cup is the receive buffer, and the tapping is the zero-window probe.
How many MORE bytes may a sender transmit right now?
rwnd − (LastByteSent − LastByteAcked).
Where is rwnd carried on the wire?
In the 16-bit Window field of TCP segments sent by the receiver.
What is the deadlock when rwnd hits 0, and its fix?
Receiver may never send a window update if no data flows; fix = sender sends periodic 1-byte zero-window probes to elicit a fresh advertisement.
Difference between rwnd and cwnd?
rwnd protects the receiver's buffer (set by receiver); cwnd protects the network (estimated by sender). Sender uses min(rwnd, cwnd).
Why is window scaling needed and how does it work?
16-bit Window maxes at 65535 bytes, too small for high bandwidth-delay links; Window Scale option multiplies the field by 2^s, negotiated at handshake.
Why subtract in-flight bytes from rwnd?
Those bytes already have reserved seats in the receive buffer; they count against the advertised room.
TCP flow control ka funda simple hai: ek fast sender ko slow receiver ko data se "dubo" dene se rokna. Receiver ke paas ek limited receive buffer hota hai jisme aaye hue bytes tab tak padte hain jab tak application unhe read() na kar le. Agar sender bina ruke bharta raha aur app slow hai, toh buffer overflow ho jayega aur data drop. Isliye receiver har segment me batata hai ki "mere paas itni jagah bachi hai" — ye number hi rwnd (receive window) hai, jo TCP header ke 16-bit Window field me jaata hai.
Sender ka rule bilkul seedha hai: jitne bytes bheje par abhi tak ACK nahi mile (yani in-flight = LastByteSent − LastByteAcked), wo rwnd se zyada nahi hone chahiye. Matlab abhi aur kitne bhej sakte ho = rwnd − in-flight. Jab ACK aata hai, window ka left edge aage khisak jaata hai (isliye "sliding" window) aur naye bytes bhejne ki jagah ban jaati hai.
Ek important case: agar receiver bilkul bhar jaye toh rwnd = 0 advertise karega, sender ruk jayega. Lekin deadlock ho sakta hai — app ne baad me data padh liya par receiver ne naya window bhej hi nahi (kyunki bhejne ko kuch tha hi nahi). Iska fix hai zero-window probe: sender chote 1-byte probes bhejta rehta hai, receiver reply me fresh window bata deta hai, aur connection phir chal padta hai.
Yaad rakho: flow control aur congestion control alag hain. rwnd receiver ka buffer bachata hai, cwnd network ko bachata hai. Sender dono me se minimum use karta hai: min(rwnd, cwnd). Exam aur real debugging dono me ye distinction bahut poocha jaata hai.