Transport and Application Layers

The transport layer adds two things the network layer refuses to provide: which process the data belongs to, and whether delivery is guaranteed. The first is just a port number and both protocols have it. The second is the whole difference between them — UDP adds ports and a checksum to IP and stops, while TCP adds a connection, sequence numbers, acknowledgements, retransmission, and two separate control loops that are constantly confused with each other. Flow control stops a fast sender overwhelming a slow receiver, and its instrument is the receiver’s advertised window. Congestion control stops the senders collectively overwhelming the network, and its instrument is 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.

UDP Adds Almost Nothing, and That Is the Feature

UDP against TCP, on what a question can hinge
PropertyUDPTCP
Connection setupNone — send and forgetThree-way handshake, so 1 RTT before any data
Header size8 bytes20 bytes minimum, more with options
ReliabilityNone; a lost datagram is simply goneAcknowledgements and retransmission
OrderingNone — the application must copeIn-order delivery by sequence number
Flow and congestion controlNeitherBoth, and they are separate mechanisms
SuitsDNS, DHCP, streaming, anything where late is worse than lostHTTP, SMTP, FTP — anything where a missing byte breaks meaning
🎯 Why DNS chose UDP, and why that is not laziness
A DNS query is one small request and one small reply, and TCP would put a three-way handshake in front of it — one full round trip of pure overhead before the question is even asked, to protect a transaction that fits in a single datagram. Retrying a lost UDP query costs one round trip; setting up TCP costs one round trip every time, lost or not. So UDP is the cheaper choice by construction, and the application handles the retry itself. The same reasoning explains the others: DHCP must work before the host has an address at all, which no connection-oriented protocol could manage; and streaming prefers a gap in the audio to a stall while a three-round-trip retransmission completes — late really is worse than lost. And DNS does fall back to TCP when a reply exceeds what a datagram can carry (historically 512 bytes), or for a zone transfer, which is the detail that makes “DNS uses UDP” only mostly true.

Two Control Loops That Are Not the Same Loop

Flow control against congestion control
QuestionFlow controlCongestion control
Protecting whom?The receiver’s bufferThe network’s routers
Who sets the limit?The receiver, explicitlyThe sender, by inference from loss
Carried how?The window field in every ACKNowhere — 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.

cwnd round by round: ssthresh 8, timeout observed in round 8
RoundcwndssthreshPhase
1–31, 2, 48Slow start — doubling
488Reaches ssthresh exactly
5–79, 10, 118Congestion avoidance — +1
812 → 18 → 6Timeout: ssthresh = 12/2, cwnd = 1
9–111, 2, 46Slow start again
1266Clamped to ssthresh, not 8
13–147, 86Congestion avoidance
⚠️ State the clamp: slow start stops at ssthresh, it does not step over it
Look at round 12. 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.
ℹ️ A socket is a pair of endpoints, which is why one port serves many clients
A TCP connection is identified by a four-tuple: source IP, source port, destination IP, destination port. That is why a web server can hold thousands of simultaneous connections on port 80 — every one of them differs in the client’s address or port, so the tuples are distinct even though one element is shared. The listening socket and the connected sockets are different objects: 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

The application protocols the syllabus names
ProtocolTransport and portThe detail that gets examined
DNSUDP 53 (TCP for large replies and zone transfers)Iterative vs recursive resolution; caching with a TTL
SMTPTCP 25Push protocol; retrieval is POP3 or IMAP, not SMTP
HTTPTCP 80Stateless; persistent vs non-persistent connections
FTPTCP 21 control, 20 dataTwo connections; the control one stays open (out-of-band)
POP3 / IMAPTCP 110 / 143POP3 typically downloads and deletes; IMAP keeps state on the server
🧠 Counting the round trips for a web page
A page is a base HTML file plus N embedded objects, and the question is how many round trips before everything has arrived. With non-persistent HTTP each object gets its own TCP connection, so each costs 1 RTT for the handshake plus 1 RTT for request and response — 2 RTT apiece, and the base page is one of them, giving 2(N + 1). So N = 1 costs 4 RTT, N = 3 costs 8, and N = 10 costs 22. With a persistent connection the handshake happens once: 1 RTT to connect, 1 RTT for the base page, and then — with pipelining, requesting all N objects together without waiting — 1 more RTT for all of them, giving 3 RTT regardless of N. Without pipelining the objects go one at a time and it is 2 + N. That is the whole reason persistent connections exist, and the shape of the saving is what to remember: non-persistent grows linearly in N, persistent-pipelined is constant. Note the model ignores transmission time and assumes no parallel connections, which is what makes it a clean counting question; a real browser opens several connections at once and lands between the two figures.
ℹ️ Iterative and recursive DNS differ in who does the walking
In recursive resolution the client asks one server and that server takes responsibility for the whole answer — querying the root, then the TLD, then the authoritative server on the client’s behalf, and returning the final result. In iterative resolution each server answers with a referral instead: “I do not know, ask this server next”, and the client walks the chain itself. The usual arrangement is a mixture, and knowing which half is which is the examinable part: a host normally makes a recursive query to its local resolver, and that resolver then makes iterative queries out to the root and downwards, because a root server that answered recursively for everyone would collapse. Caching is what makes any of it fast, and it is bounded by the TTL on each record — which is why a DNS change takes time to propagate, and why the answer to “how many queries does this lookup take” depends on what is already cached.

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.

  1. 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.
  2. 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.
  3. Which of the following are true of TCP flow control and congestion control?

    1. Flow control protects the receiver’s buffer and is advertised in the window field of every ACK
    2. Congestion control is computed by the sender, from loss, and is not carried in any header field
    3. The sender may have min(cwnd, receiver window) bytes outstanding
    4. They are the same mechanism under two names
    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.
  4. Why does DNS normally use UDP rather than TCP?

    1. Because DNS messages cannot be lost
    2. Because a query and reply fit in one datagram, so a handshake would cost more than a retry
    3. Because UDP guarantees delivery for small messages
    4. Because DNS runs at the network layer
    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.
  5. A web server has 500 established TCP connections on port 80, plus its listening socket. How many sockets exist on the server?

    1. 1 — they all share port 80
    2. 501
    3. 500
    4. 1000
    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 each accept returns 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.
  6. On receiving three duplicate ACKs, TCP Reno:

    1. Sets cwnd to 1 and re-enters slow start, as it would on a timeout
    2. Retransmits immediately and halves the window, without dropping to 1
    3. Ignores them, since duplicates carry no new information
    4. Closes the connection and re-establishes it
    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.
  7. FTP uses two TCP connections. Which statement is correct?

    1. Port 20 carries control and port 21 carries data
    2. Port 21 carries control and stays open; port 20 carries data and is opened per transfer
    3. Both connections use port 21, distinguished by sequence numbers
    4. FTP uses UDP for data and TCP only for control
    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.
  8. 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:

    1. Iterative from the host, recursive from the resolver
    2. Recursive from the host, iterative from the resolver
    3. Recursive throughout
    4. Iterative throughout
    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.