Transport and Application Layers
cwnd, which the sender computes for itself from the only signal the network gives it: loss. Keeping those two apart answers a great many questions, because the amount a sender may have outstanding is min(cwnd, receiver window) and a question can constrain either one. The congestion algorithm itself is two phases and one rule: double each round trip while below ssthresh, then add one per round trip, and on a timeout halve ssthresh and start over at 1. Then the application layer, where the syllabus names five protocols and the examinable content is mostly which transport each chose and why — and one counting result worth deriving rather than recalling: a non-persistent HTTP page costs 2(N+1) round trips and a persistent pipelined one costs 3, whatever N is.Two Control Loops That Are Not the Same Loop
| Question | Flow control | Congestion control |
|---|---|---|
| Protecting whom? | The receiver’s buffer | The network’s routers |
| Who sets the limit? | The receiver, explicitly | The sender, by inference from loss |
| Carried how? | The window field in every ACK | Nowhere — cwnd is local to the sender |
| What the sender may have outstanding | ← min(cwnd, receiver window) → | ← the smaller of the two always wins → |
TCP congestion control is two phases with one switch between them. In slow start the window doubles every round trip — which is exponential, not slow; the name means it starts small. Once cwnd reaches ssthresh the sender moves to congestion avoidance and adds one segment per round trip, probing linearly for the point at which the network complains. A timeout is read as serious congestion: ssthresh becomes half the current window and cwnd restarts at 1. The trajectory below was simulated with ssthresh starting at 8 and a timeout observed in round 8.
| Round | cwnd | ssthresh | Phase |
|---|---|---|---|
| 1–3 | 1, 2, 4 | 8 | Slow start — doubling |
| 4 | 8 | 8 | Reaches ssthresh exactly |
| 5–7 | 9, 10, 11 | 8 | Congestion avoidance — +1 |
| 8 | 12 → 1 | 8 → 6 | Timeout: ssthresh = 12/2, cwnd = 1 |
| 9–11 | 1, 2, 4 | 6 | Slow start again |
| 12 | 6 | 6 | Clamped to ssthresh, not 8 |
| 13–14 | 7, 8 | 6 | Congestion avoidance |
cwnd is 4 and ssthresh is 6, so doubling would give 8 — past the threshold. The convention used here, and the one the RFCs describe, is that slow start increases by one segment per acknowledgement and therefore stops exactly at ssthresh, giving 6 rather than 8. Some textbooks present slow start as pure doubling and let it overshoot, which would give 8 and shift every later round. Neither reading is silly, which is exactly why a question that gives an ssthresh that is not a power of two and does not state its convention is ambiguous rather than hard — the same situation as the TLB convention in the operating-systems section. Practical advice: if the question’s ssthresh is a power of two you will never meet the ambiguity, and if it is not, say which convention you used. Two more details get asked separately. A triple duplicate ACK is treated as milder than a timeout: fast retransmit resends immediately and fast recovery halves the window rather than dropping to 1, because duplicate ACKs prove packets are still arriving. And the sender is always limited by min(cwnd, receiver window), so a question can cap the throughput with either number.listen creates one socket that only accepts, and each accept returns a new socket bound to that specific four-tuple. UDP has no connection and therefore no four-tuple — a UDP socket is identified by its own address and port alone, which is why one UDP socket receives datagrams from every sender and the application must look at each packet’s source itself. The examinable form is usually a counting question: how many sockets exist on a server with n established connections plus its listener, and the answer is n + 1.Five Protocols, and One Counting Result
| Protocol | Transport and port | The detail that gets examined |
|---|---|---|
| DNS | UDP 53 (TCP for large replies and zone transfers) | Iterative vs recursive resolution; caching with a TTL |
| SMTP | TCP 25 | Push protocol; retrieval is POP3 or IMAP, not SMTP |
| HTTP | TCP 80 | Stateless; persistent vs non-persistent connections |
| FTP | TCP 21 control, 20 data | Two connections; the control one stays open (out-of-band) |
| POP3 / IMAP | TCP 110 / 143 | POP3 typically downloads and deletes; IMAP keeps state on the server |
Key takeaways
- UDP adds ports and a checksum to IP and nothing else; its 8-byte header is the whole story.
- DNS uses UDP because a handshake would cost more than a retry; it falls back to TCP for large replies.
- Flow control protects the receiver and is advertised; congestion control protects the network and is inferred.
- A sender may have min(cwnd, receiver window) outstanding — the smaller always wins.
- Slow start doubles per RTT and stops at ssthresh; congestion avoidance adds one per RTT.
- A timeout halves ssthresh and restarts cwnd at 1; three duplicate ACKs only halve the window.
- A TCP connection is a four-tuple, which is how one port serves thousands of clients.
- FTP uses two connections, 21 for control and 20 for data — control stays open, out of band.
- Non-persistent HTTP costs 2(N+1) RTT; persistent with pipelining costs 3, whatever N is.
- A host queries its resolver recursively; the resolver queries the root iteratively.
Practice questions (8)
Attempt each one before opening the answer. Every explanation names the tempting wrong option as well as the right one, because that is where marks are lost.
A TCP connection starts with ssthresh = 8 segments. Slow start begins with cwnd = 1 and doubles each RTT. In the round in which cwnd reaches 12, a timeout occurs. The new value of ssthresh is ______ segments
Numerical answer — type the value.
Show answer
Answer: 6
6. A timeout sets ssthresh to half the current congestion window and restarts cwnd at 1, so ssthresh = 12/2 = 6. Trace how cwnd got to 12: slow start doubles 1, 2, 4, and reaches 8 exactly, which is ssthresh, so the sender switches to congestion avoidance and adds one per round trip — 9, 10, 11, 12. The timeout at 12 therefore gives ssthresh 6, and the next rounds are 1, 2, 4, then 6 rather than 8, because slow start stops at ssthresh instead of stepping over it. Two wrong answers are worth naming. 4 halves the old ssthresh (8) instead of the current window — the rule is about cwnd, not the previous threshold. And 1 reports the new cwnd rather than the new ssthresh; the timeout changes both, and the question asked for the threshold.A web page consists of a base HTML file and 3 embedded objects. Using non-persistent HTTP with one object fetched at a time, and ignoring transmission times, the total time is ______ RTT
Numerical answer — type the value.
Show answer
Answer: 8
8 RTT. Non-persistent HTTP opens a fresh TCP connection for every object, and each object therefore costs two round trips: one for the three-way handshake and one for the request and its response. There are 4 objects in total — the base page plus 3 embedded — so the cost is 2 × 4 = 8, which is the general formula 2(N + 1). Contrast the alternatives on the same page: a persistent connection with pipelining costs 1 RTT to connect, 1 for the base page and 1 more for all three objects requested together — 3 RTT, and 3 no matter how many objects there are. Persistent without pipelining costs 2 + N = 5. The commonest wrong answer is 6, from counting 2 RTT for the base page and then only 1 per object, which forgets that each new connection needs its own handshake — that is precisely what makes the connection non-persistent.Which of the following are true of TCP flow control and congestion control?
Show answer
Answer: A — Flow control protects the receiver’s buffer and is advertised in the window field of every ACK; B — Congestion control is computed by the sender, from loss, and is not carried in any header field; C — The sender may have min(cwnd, receiver window) bytes outstanding
A, B and C. A and B together are the whole distinction and the asymmetry is the point: flow control is explicit, because the receiver knows its own buffer and says so in the window field, while congestion control is inferred, because no router tells a sender it is congested — the sender deduces it from loss. C follows: the two limits apply simultaneously and the binding one is whichever is smaller, which is why a question can throttle a connection with either number and why quoting cwnd alone is not an answer. D is false and is the confusion the section exists to prevent: they protect different things, are set by different parties, and can bind at different times — a fast receiver on a congested path is limited by cwnd, and a slow receiver on an idle path is limited by the advertised window. Worth adding: UDP has neither, which is exactly why an application over UDP that wants either has to implement it itself.Why does DNS normally use UDP rather than TCP?
Show answer
Answer: B — Because a query and reply fit in one datagram, so a handshake would cost more than a retry
The transaction is one small request and one small reply, and TCP would insist on a three-way handshake first — a full round trip of pure overhead, paid on every lookup, to protect something that fits in a single datagram. Retrying a lost UDP query also costs one round trip, but only on the rare occasions a query is actually lost, so UDP is cheaper in expectation. Option A is false and irrelevant: DNS messages certainly can be lost, which is why resolvers implement their own timeout and retry. Option C states the opposite of UDP’s contract — UDP guarantees nothing at any size, and that is its defining property. Option D misplaces DNS, which is an application layer protocol. And the honest qualification: DNS does switch to TCP when a reply is too large for a datagram or for a zone transfer, so “DNS uses UDP” is true of the common case rather than universally.A web server has 500 established TCP connections on port 80, plus its listening socket. How many sockets exist on the server?
Show answer
Answer: B — 501
501 — one socket per established connection, plus the listening socket, which is a different kind of object: it only accepts, and eachacceptreturns a new socket. Option A is the misconception the question targets, and the resolution is that a TCP connection is identified by a four-tuple — source IP, source port, destination IP, destination port — so the 500 connections are distinct even though the server’s IP and port are identical in all of them; they differ in the client’s address or port. That is exactly how one well-known port serves thousands of clients at once. Option C forgets the listener, which continues to exist and to accept new connections. Option D double-counts, perhaps by counting both endpoints — but the other end of each connection is a socket on the client, not on this server. Worth contrasting: a UDP socket has no four-tuple and no per-client socket, so one UDP socket receives from every sender and the application inspects each datagram’s source itself.On receiving three duplicate ACKs, TCP Reno:
Show answer
Answer: B — Retransmits immediately and halves the window, without dropping to 1
Three duplicate ACKs are read as a milder signal than a timeout, and the reason is the useful part: duplicates only arrive because later segments are still getting through, so the path is evidently alive and one segment was lost rather than the network having collapsed. Fast retransmit therefore resends the missing segment at once without waiting for the timer, and fast recovery halves the window instead of dropping to 1. Option A is the timeout response, and treating the two signals identically is the confusion this question exists to test — a timeout means silence, which is much worse evidence than a stream of duplicates. Option C is wrong about the information content: a duplicate ACK says I am still missing the same byte, and I received something after it, which is precisely the loss signal. Option D describes nothing TCP does; congestion is handled by adjusting the window, never by tearing the connection down.FTP uses two TCP connections. Which statement is correct?
Show answer
Answer: B — Port 21 carries control and stays open; port 20 carries data and is opened per transfer
Control on 21, data on 20. The control connection is established first, stays open for the whole session, and carries commands and replies; a separate data connection is opened for each file transfer or directory listing and closed when it finishes. This arrangement is called out-of-band control, and it is FTP’s distinguishing feature — HTTP by contrast sends commands and data over one connection, which is in-band. Option A swaps the ports, which is the commonest error and worth anchoring: the lower number carries data, which feels backwards, so it is worth memorising as the exception it is. Option C could not work: two connections between the same pair of hosts on the same ports would have identical four-tuples and be indistinguishable, which is exactly why a second port is needed. Option D is wrong about FTP, which is TCP throughout — a file transfer is precisely the case where a missing byte destroys the result.A host sends a query to its local DNS resolver, which then queries the root server, a TLD server and an authoritative server in turn. The two query types used are:
Show answer
Answer: B — Recursive from the host, iterative from the resolver
Recursive from the host, iterative from the resolver — and the description in the question already tells you so, which is the skill being tested. The host asks one server and expects the finished answer, which is what recursive means: the resolver takes responsibility for however much work it needs. The resolver then asks the root, the TLD server and the authoritative server in turn, each returning a referral rather than a final answer, which is what iterative means: the asker walks the chain itself. Option C is the arrangement the root servers could not survive — answering recursively for every host on the internet would make each root server do the whole internet’s resolution work, so they answer with referrals only. Option A reverses the roles, which would mean a host doing its own walk while the resolver did the recursion for it — a contradiction. Worth adding what makes this fast in practice: each record is cached for its TTL, so the counting question “how many queries does this lookup need” always depends on what is already cached.