A TCP connection is two buffers and a handful of variables at each end. Its sequence numbers count bytes rather than packets, and that single fact is what makes the rest of TCP readable.
Words you will meet
- Full-duplex — data flows both ways at once on one connection.
- MTU — the largest frame a link will carry, typically 1,500 bytes.
- MSS — the largest amount of application data in one segment, typically 1,460 bytes.
- Sequence number — the byte-stream number of the first byte in this segment.
- Acknowledgement number — the number of the next byte this host expects.
- Piggybacking — carrying an acknowledgement inside a segment that already had data to send.
Why this matters
Section 3.4 built a toolkit and asked what you would build. This section starts on what was actually built.
TCP (Transmission Control Protocol) Transmission Control Protocol The Internet transport protocol that delivers data reliably and in order, with flow control and congestion control. introduced in ch. 1 is defined in RFC (Request For Comments) Request For Comments The name of an IETF standards document. There are currently nearly 9000 of them. introduced in ch. 1 793 and refined by RFC 1122, RFC 2018, RFC 5681 and RFC 7323. It uses almost everything section 3.4 developed — error detection, retransmission, cumulative acknowledgements, timers, and header fields for sequence and acknowledgement numbers.
Get the numbering right here and the next four sections follow easily. Get it wrong and none of them will make sense.
What a connection is, and is not
TCP transmission control protocol Simple The Internet’s reliable transport protocol: connection-oriented, ordered, flow- and congestion-controlled. Precise TCP, defined in RFC 793 and refined by RFC 1122, RFC 2018, RFC 5681 and RFC 7323. It provides a full-duplex, point-to-point connection between exactly two processes, delivers a byte stream that is uncorrupted, gap-free, duplicate-free and in order, and regulates its own sending rate for both the receiver’s sake and the network’s. Its state lives only in the two end systems; routers know nothing about connections. introduced in ch. 3 — open in glossary is connection-oriented: before one process can send data to another, the two must handshake — exchange preliminary segments that establish the parameters of the transfer. Both sides initialise a good many state variables in the process.
It is not a circuit
The “connection” is logical. Its common state resides only in the two end systems.
Recall from section 3.1 that TCP runs only in end systems, never in routers or link-layer switches. So the intermediate elements do not maintain TCP connection state at all — in the book’s phrase, they see datagrams, not connections.
That is the difference from the circuit switching of section 1.3.2, where the network itself reserved capacity and remembered who it belonged to. Nothing is reserved for a TCP connection. Its segments queue at routers exactly like everyone else’s.
Three more properties follow. A TCP connection provides full-duplex service. If there is a connection between process A and process B, data can flow from A to B at the same time as data flows from B to A. It is always point-to-point, between a single sender and a single receiver — multicasting is not possible. As the book puts it, with TCP two hosts are company and three are a crowd.
From socket to segment
Once the connection is established, the client process passes a stream of bytes through the socket. From that moment the data is in TCP’s hands.
The client process passes a stream of bytes through the socket — the door of section 2.1.2. Once through, the data belongs to TCP.
Two buffers and some variables at each end, and nothing anywhere else. Step through what happens to one file.
Read all steps as text
- 1 — The application writes into a socket — The client process passes a stream of bytes through the socket — the door of section 2.1.2. Once through, the data belongs to TCP.
- 2 — TCP puts it in the send buffer — The send buffer is one of the buffers set aside during the three-way handshake. It exists before any data is sent.
- 3 — TCP decides when to send, and how much — From time to time TCP grabs a chunk from the buffer and hands it down. RFC 793 is famously relaxed about the timing: TCP should "send that data in segments at its own convenience". The chunk is at most one MSS.
- 4 — And again, and again — A large file becomes a run of full-MSS segments, with only the last one short. Lin’s 372 kB page is 255 segments of 1,460 bytes.
- 5 — The receive buffer holds it until the application reads — Arriving data is placed in the receive buffer. The application reads from there — not necessarily at the moment the data arrives, which is exactly the gap flow control exists to manage.
- 6 — Each side has both — TCP is full-duplex, so every connection has a send buffer and a receive buffer at each end, plus variables. That set of buffers and variables IS the connection — no router holds any part of it.
The MSS, and the terminology the book apologises for
The maximum segment size maximum segment size Simple The largest amount of application data TCP will put in one segment — headers not counted. Precise The MSS. It is normally derived from the largest link-layer frame the sending host can emit, the maximum transmission unit, so that a segment plus its 40 bytes of TCP and IP headers still fits in one frame. With the 1,500-byte MTU of Ethernet and PPP, a typical MSS is 1,460 bytes. Note that it limits the *data*, not the whole segment — confusing, but firmly established. introduced in ch. 3 — open in glossary is the largest chunk TCP will take from the send buffer for one segment.
TCP takes those chunks from the send buffer send buffer Simple Memory in the sending host holding bytes the application has written but TCP has not finished sending. Precise One of the buffers set aside during the three-way handshake. The application writes a byte stream into the socket; TCP takes chunks out of this buffer at its own convenience, up to the maximum segment size, adds a header, and passes each segment to the network layer. introduced in ch. 3 — open in glossary , and the data arriving at the far end lands in a receive buffer receive buffer Simple Memory in the receiving host holding bytes that have arrived but the application has not read yet. Precise The buffer into which TCP places the data from correctly received, in-order segments. The application reads the byte stream out of it, not necessarily at the moment the data arrives. Its spare room is what the receive window advertises, and its size is what flow control protects. introduced in ch. 3 — open in glossary until the application reads it.
The MSS is derived from the link below. First find the maximum transmission unit maximum transmission unit Simple The largest frame a link will carry. Precise The MTU: the length of the largest link-layer frame that can be sent on a given link. Ethernet and PPP both use 1,500 bytes. The path MTU is the largest frame that can cross every link from source to destination [RFC 1191]; discovering it lets a sender choose an MSS that never needs fragmenting. introduced in ch. 3 — open in glossary — the largest link-layer frame the sending host can emit. Then set the MSS so that the segment plus its TCP and IP (Internet Protocol) Internet Protocol The network-layer protocol that defines the datagram format and addressing every Internet device must use. introduced in ch. 1 headers, typically 40 bytes, still fits in one frame. Ethernet and PPP (Point-to-Point Protocol) Point-to-Point Protocol A link-layer protocol; a datagram may travel over Ethernet on one link and PPP on the next. introduced in ch. 1 both use a 1,500-byte MTU, so a typical MSS is 1,460 bytes.
Now the warning. The MSS is the maximum amount of application-layer data in the segment, not the maximum size of the segment including headers. The book calls this terminology confusing, notes that we have to live with it because it is well entrenched, and moves on. So will we — but read the name as maximum segment payload in your head.
The segment size therefore comes from the link, not from TCP:
What each symbol means
- MTU — the largest frame this link will carry (bytes)
- MSS — the largest amount of application data in one segment (bytes)
Read aloud: Take the biggest frame the link allows, and leave room for the two headers. What is left is how much of the application’s data can travel in one segment.
Maximum segment size1,460 bytes of application data
the largest frame this link will carry is the MTU = 1,500 bytes a segment must leave room for its TCP and IP headers = 40 bytes MSS = 1,500 − 40 = 1,460 bytes so 97.3 % of each frame is the application's data note: the MSS bounds the DATA, not the whole segment — the segment is 1,500 bytes
Change any number above and the arithmetic re-runs, carrying the units through.
The defaults are Ethernet and PPP, which both use a 1,500-byte MTU. Read the last line of the working — it is the piece of terminology the book warns you about.
There are also methods for discovering the path MTU, the largest frame that can cross every link from source to destination. The MSS can then be set from that instead [RFC 1191].
The segment
Click any box to read what that part of the message is for.
Every field, as text
- Source port # — 16 bits — part of the four-tuple (example: 49153)
- Dest port # — 16 bits — part of the four-tuple (example: 80)
- Sequence number — 32 bits — the byte-stream number of the first byte of data here (example: 3841271296)
- Acknowledgment number — 32 bits — the next byte this host expects to receive (example: 2264810497)
- Header length — 4 bits — header size in 32-bit words (example: 5)
- Unused — 4 bits — reserved
- CWR — 1 bits — Congestion Window Reduced
- ECE — 1 bits — ECN Echo
- URG — 1 bits — urgent data present
- ACK — 1 bits — the acknowledgment number is valid
- PSH — 1 bits — pass this up immediately
- RST — 1 bits — reset the connection
- SYN — 1 bits — connection setup
- FIN — 1 bits — no more data from me
- Receive window — 16 bits — how many bytes the receiver can still accept (example: 65535)
- Internet checksum — 16 bits — did any bit change?
- Urgent data pointer — 16 bits — where the urgent data ends
Twenty bytes when the options are empty, which is usual. Click any field. The eight flag bits are drawn vertically, exactly as the book draws them.
Two of the flag names are used constantly from here on. SYN (synchronize) synchronize The TCP flag bit that marks a connection-establishment segment. Set in the first two segments of the three-way handshake (§3.5.6). introduced in ch. 3 is set on the segments that open a connection; FIN (finish) finish The TCP flag bit meaning "I have no more data to send". A full teardown uses two, one from each side (§3.5.6). introduced in ch. 3 is set on the segments that close it. Both belong to section 3.5.6.
The book says six flag bits. The figure has eight.
The text of this section states that “the flag field contains 6 bits”, and then describes eight flags: CWR, ECE, URG, ACK, PSH, RST, SYN and FIN. Figure 3.29 draws all eight, and the arithmetic only works with eight — 4 bits of header length, 4 unused, 8 flags and a 16-bit receive window make exactly 32.
Six is the original count from RFC 793: URG, ACK, PSH, RST, SYN, FIN. CWR and ECE were added later, by RFC 3168, for the explicit congestion notification of section 3.7.2, taking two of the six reserved bits and leaving four. The sentence is a leftover; the figure is current. Follow the figure.
In plain words
Twenty bytes of header, of which the two sequence-number fields take eight.
For a large file that overhead is trivial — 20 bytes on 1,460 is under 1.4 %. For an interactive application it is not. A Telnet or ssh segment often carries one byte of data, making the whole segment 21 bytes: 95 % header.
Sequence numbers count bytes
This is the fact to hold on to.
TCP views data as an unstructured but ordered stream of bytes, and its sequence numbers are over that stream — not over the series of transmitted segments. So:
The sequence number for a segment is the byte-stream number of the first byte in the segment.
Take a 500,000-byte file with an MSS of 1,000 bytes, numbering the first byte 0. TCP constructs 500 segments. The first is given sequence number 0, the second 1,000, the third 2,000, and so on. The sequence number is not a count of segments; it is a position in the file.
Acknowledgement numbers are trickier
TCP is full-duplex, so host A may be receiving from B while sending to B. Each segment arriving from B has a sequence number for the B-to-A stream.
The acknowledgement number acknowledgement number Simple The number of the next byte this host is waiting for from the other side. Precise The 32-bit TCP header field holding the sequence number of the next byte the sender of this segment expects to receive. Because it names the next byte wanted rather than the last byte received, it acknowledges everything before it — TCP acknowledges cumulatively, only up to the first missing byte. introduced in ch. 3 — open in glossary that A puts in its segment is the sequence number of the next byte A is expecting from B.
Two examples, both the book’s.
Simple. A has received bytes 0 through 535 from B. It is waiting for byte 536, so it puts 536 in the acknowledgement field.
Not simple. A has received bytes 0–535 and bytes 900–1000, but not 536–899. A is still waiting for byte 536, so its next segment to B again carries 536. The 101 bytes it is already holding go entirely unmentioned — there is no field in which to mention them.
Because TCP only acknowledges bytes up to the first missing byte, TCP is said to provide cumulative acknowledgements.
What happens to those out-of-order bytes?
In that second example A received the third segment before the second. So what does a host do with an out-of-order segment out-of-order segment Simple A segment that arrives before an earlier one that has not turned up yet. Precise A segment whose sequence number is beyond the next expected byte, leaving a gap. The TCP RFCs do not say what to do with it: an implementation may discard it, which simplifies the receiver, or keep it and wait for the gap to be filled, which wastes less link capacity. Real implementations keep it, which is one reason TCP is not purely Go-Back-N. introduced in ch. 3 — open in glossary ?
The TCP RFCs do not say. The decision is left to whoever implements TCP, and there are two choices:
- Discard it immediately — which, as section 3.4.3 showed, simplifies the receiver considerably.
- Keep the out-of-order bytes and wait for the missing ones to fill the gap.
The second is more efficient in terms of network capacity, and is the approach taken in practice. Remember that when section 3.5.4 asks whether TCP is Go-Back-N or selective repeat — its acknowledgements say one thing and its buffering says another.
Where the numbering starts
The examples above assumed the first byte is numbered 0. In truth, both sides of a connection randomly choose an initial sequence number.
The reason is a hazard section 3.4.4 already met. A segment from an earlier, already-terminated connection between the same two hosts — using the same port numbers — may still be wandering in the network. Random starting numbers make it very unlikely that such a segment looks valid in the new connection [Sunshine 1978].
And the sequence-number space is finite, so at a high enough rate it wraps:
What each symbol means
- 2³² — distinct byte numbers a 32-bit field can hold (bytes)
- R — the rate the connection actually achieves (bits/s)
Read aloud: How long can this connection run before it starts reusing byte numbers it has used before?
Time to wrap344 s
a 32-bit field counts 4,294,967,296 distinct byte numbers that is 3.436e+10 bits of data before the numbering repeats at 100 Mbps the space wraps in 344 s a packet is assumed to survive at most 180 s in the network 344 s > 180 s — an old copy is dead before its number comes round again
Change any number above and the arithmetic re-runs, carrying the units through.
Section 3.4.4 needed old copies to be dead before a number is reused, and assumed a three-minute packet lifetime. Try 1 Gbps, then 10 Gbps.
Random starting points do not fix a long connection
Randomising the start protects a new connection from an old one. It does nothing for a single connection that runs long enough to reuse its own numbers.
Try the calculator at 1 Gbps: 32 bits of byte numbering wraps in about 34 seconds — well inside the three-minute packet lifetime section 3.4.4 assumed. At 10 Gbps it is 3.4 seconds. Only at 100 Mbps and below is there real headroom, at 344 seconds.
This is what the timestamp option in RFC 7323 is for. It lets a receiver tell a wrapped sequence number from a stale one, using a field the header did not originally have.
Telnet, as a case study in numbering
Telnet, defined in RFC 854, is an interactive remote-login protocol over TCP. It is worth a look because it makes the numbering visible. (In practice ssh has replaced it, because Telnet sends everything — passwords included — unencrypted; section 8.7 covers the consequences.)
Every character the user types is sent to the remote host, which echoes a copy back so it can be displayed. Each character therefore crosses the network twice between the keystroke and the letter appearing on screen.
Click any arrow to see what that message says and why it is sent.
The user types C. Follow the numbers: every acknowledgement is one past the last byte received. Click each arrow.
Read this diagram as text
- Host A sends Seq=42, ACK=79, data = ‘C’ to Host B. The client’s first segment carries sequence number 42 — the byte-stream number of the single byte it contains. It has received nothing yet, so its acknowledgement number is 79: the first byte it expects from the server.
- Host B sends Seq=79, ACK=43, data = ‘C’ to Host A. This segment does two jobs at once. It acknowledges the client’s byte 42 by putting 43 in the acknowledgement field — the next byte it expects. And it echoes the character back, which is what Telnet does so the user can see what they typed. The acknowledgement rides along on a data segment: it is piggybacked.
- Host A sends Seq=43, ACK=80, no data to Host B. Purely an acknowledgement of the echoed character: 80 means "I have byte 79, send me 80 next". Its data field is empty, and there was no data of its own to piggyback on. It still carries a sequence number, 43, simply because the field exists and must hold something.
Lifelines, left to right: Host A (host), Host B (server).
In plain words
Three segments for one letter, and the numbers tell the whole story:
- 42 → 43. The client’s byte is number 42, so the server asks for 43 next.
- 79 → 80. The server’s echoed byte is number 79, so the client asks for 80.
- The middle segment does two jobs at once — echoing the character and acknowledging the original. That is piggybacking piggybacking Simple Carrying an acknowledgement inside a segment that is already going the other way with data. Precise Placing the acknowledgement for data received in one direction into the header of a segment carrying data in the other direction, rather than sending a separate segment. It is free, because TCP is full-duplex and every segment has an acknowledgement field anyway. introduced in ch. 3 — open in glossary , and it is free, because every segment has an acknowledgement field whether it uses it or not.
The third segment has nothing to piggyback on, so it travels almost empty: 20 bytes of header to carry the number 80.
Case history — Cerf, Kahn and TCP/IP (Transmission Control Protocol / Internet Protocol) Transmission Control Protocol / Internet Protocol The collective name for the Internet's principal protocols. It became the ARPAnet standard on 1 January 1983. introduced in ch. 1
In the early 1970s packet-switched networks were proliferating, the ARPAnet among many, and each had its own protocol. Vinton Cerf and Robert Kahn saw the importance of interconnecting them, and invented a cross-network protocol called TCP/IP. They published it in May 1974 in IEEE (Institute of Electrical and Electronics Engineers) Institute of Electrical and Electronics Engineers The body whose 802 committee standardises Ethernet and WiFi. introduced in ch. 1 Transactions on Communications Technology [Cerf 1974].
They began by seeing it as a single entity. It was later split into its two parts, TCP and IP, operating separately — which is the division this whole book is organised around.
The design predates personal computers, smartphones, Ethernet, DSL (Digital Subscriber Line) Digital Subscriber Line Home Internet access over the existing telephone wire. introduced in ch. 1 , WiFi (IEEE 802.11 wireless LAN) IEEE 802.11 wireless LAN Wireless LAN access; a user must be within a few tens of metres of the access point. WiFi is a trade name, not an abbreviation. introduced in ch. 1 , the Web and streaming video. Cerf and Kahn wanted a protocol that would support applications not yet imagined and let arbitrary hosts and link technologies interoperate. In 2004 they received the ACM’s Turing Award for it.
Check yourself
Check yourself
0 of 6 answered1.A TCP connection is established between Bangkok and Frankfurt, crossing eleven routers. Where does the connection actually exist?
2.predictSet the MSS calculator to an MTU of 1,500 bytes and 40 bytes of header. What does 1,460 describe?
Read the last line of the working.
3.Host A has received bytes 0 through 535 from B, and also bytes 900 through 1000. Bytes 536 to 899 are missing. What acknowledgement number does A send?
4.predictIn the Telnet exchange the user types one character. Why does the third segment have a sequence number when it carries no data?
5.predictSet the wrap calculator to 32 bits and 1 Gbps. Is the sequence space large enough?
Compare it with the three-minute maximum packet lifetime from section 3.4.4.
6.What does a TCP receiver do with a segment that arrives out of order?
What to remember
- A TCP connection is buffers and variables in the two end systems. Routers hold nothing about it — it is logical, not a circuit.
- The MSS is derived from the link’s MTU: 1,500 − 40 = 1,460 bytes. It bounds the data, not the segment.
- Sequence numbers count bytes, not packets. The acknowledgement number is the next byte expected, one past the last byte received in order, and that is what makes acknowledgements cumulative.