1. Library
  2. Computer Networks
  3. Tcp and Udp
  4. Tcp

Updated 9 hours ago

When you send data across the Internet, you're trusting it to a network that loses packets, delivers them out of order, and sometimes delivers them twice. TCP's job is to make that chaos invisible. It does this with two numbers in every packet header: a sequence number that says "this is byte 1000," and an acknowledgment number that says "I've received everything up to byte 999, send me 1000 next."

This is the entire mechanism. Everything else—retransmission, reordering, duplicate detection—emerges from these two numbers.

Every Byte Gets a Number

TCP doesn't think in packets. It thinks in bytes.

When you transmit data, TCP treats it as a continuous stream. Each byte in that stream has a sequence number. If you send a segment containing 500 bytes starting at sequence number 1000, you've sent bytes 1000 through 1499. The next segment starts at 1500.

This byte-level accounting is what makes TCP reliable. The receiver knows exactly which bytes it has and which are missing. If bytes 1000-1499 and 2000-2499 arrive but 1500-1999 don't, the receiver knows precisely what's missing and can wait for it.

The Acknowledgment Convention

Here's where TCP's elegance shows. The acknowledgment number doesn't say "I got it." It says "I'm ready for what comes next."

If you receive bytes 1000-1499, you acknowledge with 1500. Not 1499 (the last byte received), but 1500 (the next byte expected). This tiny convention simplifies everything. The sender always knows: if the acknowledgment says 1500, everything before 1500 has arrived safely.

Acknowledgments are also cumulative. Receive three segments in quick succession? Send one acknowledgment for all of them. The acknowledgment for byte 3000 implicitly confirms that bytes 1000-2999 all arrived. If an acknowledgment gets lost, the next one covers the same ground.

How Reliability Emerges

The sender keeps a copy of everything it transmits. When an acknowledgment arrives, it can discard that data—the receiver has it. If no acknowledgment comes within a timeout period, the sender transmits again.

The receiver uses sequence numbers to reassemble order from chaos. Segments can take different paths through the network and arrive in any order. Bytes 2000-2499 might arrive before 1000-1499. The receiver buffers them, watches the sequence numbers, and delivers data to the application in the correct order.

Duplicates are trivial to detect. If you receive the same sequence numbers twice, you already have that data—discard the duplicate.

Why Connections Start with Random Numbers

TCP connections don't start counting from zero. During the three-way handshake, each side picks a random Initial Sequence Number (ISN).

This prevents a subtle problem. Imagine you had a connection between the same two machines and ports yesterday. Some packets from that old connection got delayed in the network. If the new connection started at zero, those old packets might have sequence numbers that look valid. Random ISNs make this collision astronomically unlikely.

Both sides exchange their ISNs during the handshake. Now each knows where the other's byte stream begins. TCP is full-duplex—both sides send and receive simultaneously, each maintaining independent sequence number spaces.

A 1970s Design Decision Still Running the Internet

Sequence numbers are 32-bit integers: 0 to 4,294,967,295. When TCP was designed, transmitting 4.3 GB seemed like it would take forever. The sequence space would never wrap.

Today, a 10 Gbps connection wraps that counter in under four seconds.

The protocol adapted. TCP timestamps and other mechanisms now help distinguish "sequence number 1000 from four seconds ago" from "sequence number 1000 right now." But the original 32-bit field remains—backward compatibility is a powerful force.

Watching It Work

A 2000-byte file download, with the server's ISN at 50000:

  1. Server sends bytes 50000-50999 (sequence number 50000)
  2. Client acknowledges 51000 ("got it, ready for 51000")
  3. Server sends bytes 51000-51999 (sequence number 51000)
  4. Client acknowledges 52000 ("got everything")

If segment two gets lost:

  1. Server sends bytes 50000-50999
  2. Client acknowledges 51000
  3. Server sends bytes 51000-51999 (lost in transit)
  4. Client keeps acknowledging 51000
  5. Server times out, retransmits bytes 51000-51999
  6. Client acknowledges 52000

The client never saw the lost packet. It just kept saying "I need 51000" until 51000 arrived.

The Elegant Constraint

TCP took the simplest possible mechanism—number the bytes, confirm receipt—and made it sufficient for reliable communication over an unreliable network.

No complex negotiation. No sophisticated error codes. Just: "Here are bytes 1000-1499" and "Ready for 1500." Everything else follows.

Frequently Asked Questions About TCP Sequence Numbers

Was this page helpful?

😔
🤨
😃