Home CPSC 414

The Transport Layer: TCP



We have seen that UDP is not a reliable transport protocol. Now, we will look at the TCP protocol which is reliable. TCP is a very complex protocol. We will look at the ideas behind at, but it is a large and deep topic.


Handling Errors

A packet sent with TCP may potentially be corrupted. Like UDP, TCP packets contain checksums which are checked when a packet is received. Unlike UDP, TCP will resend packets which are corrupted.

TCP sends acknowledgement packets (ACKs) when a packet was received successfully and negative acknowledgement packets (NAKs) when one was corrupted:

When a packet is lost, it is re-transmitted until it receives the ACK message.

One issue with this, however, is that the ACK and NAK packets themselves can be corrupted!

If the sender receives a garbled response, what should it do? There are two possible approaches:

  1. It could ask the receiver to re-send the acknowledgement. This would be sort of a meta-NAK. However, what if that communication is corrupted? We would need a meta-meta-NAK. This would lead us to the Two Generals problem again.
  2. If the acknowledgement is garbled, the sender could just re-send the packet anyway. If it was a NAK, everything is fine. However, if the acknowledgement was actually an ACK, then the receiver will now be receiving a duplicate packet.

TCP takes option 2. Now the receiver needs to distinguish a new packet from a duplicate one. To do this, TCP includes a "sequence number" field with all packets. When it receives a packet, it checks if the sequence number is a new one or not.


Handling Dropped Packets

In addition to corrupted packets, TCP handles lost packets. When a sender sends a packet, it is responsible for ensuring that the packet is received. When a packet (or the ACK for it) is lost, it must re-send the packet.

However, how can a sender know if a packet was lost or just delayed? From the sender's point of view, the only evidence of a dropped packet is the lack of an ACK for it. But maybe the ACK is on its way and just taking a while.

The sender has 2 constraints:

  1. If they wait a long time to re-send, they are delaying the communication.
  2. If they don't wait long enough, they will send many duplicate packets which is wasteful.

TCP has the sender wait long enough that packet loss is likely but not guaranteed.


Handling Order

TCP also handles the problem of packets received out of order. This is also handled with the sequence numbers. Whenever a packet is sent, there is a sequence number sent along with it. This sequence number starts at 0, and increments for each byte which is sent.

So if a sender wants to send a 5 kilobyte file, which gets broken into 4 packets (1500 bytes is about as big as packets get). It could then send the packets with the following sequence numbers:

Sequence numberSize

When the receiver gets a packet, it will check if the sequence number is a duplicate (to avoid duplicate packets), and also use it to put the packets back into the correct order.



This is enough to give TCP the reliability that it promises. However, being reliable isn't the only goal of TCP. It also strives to be as fast as it can be. As described thus far, a sender basically will do this:

  1. Send the next packet.
  2. Wait for the acknowledgement.
  3. If the ACK comes within a set timeout, go to step 1.
  4. If not, re-send the same packet and go to step 2.

This is called a "stop and wait" protocol. Because we wait for a response after each send. The following figure depicts this:

Here the data transmissions are represented with the thicker bars. The sender only sends data after receiving a response.

A faster approach is to pipeline the transmission. This will entail sending multiple packets, one after the other, before hearing back on whether the first was received correctly or not.

Here we are pipelining by sending three packets before waiting for acknowledgement. This decreases transfer time because we can send three packets in a little less than the time to send one packet.

However it complicates the protocol somewhat. Now the receiver may receive packets 0 and 2, but not packet 1. How should it address these issues?



One approach to allowing for pipelining is the Go-Back-N (GBN) protocol. Here, we have some maximum number of packets that are allowed to be in flight at any one time.

We can send up to N packets before getting acknowledgement, but cannot go past that number. The following diagram gives an example of a GBN protocol when N is 8:

Here we have sent 5 packets that have not yet been acknowledged. Because N is 8, we can send 3 more, but cannot go past that.

The set of packets that can be in flight is sometimes called a "window". As the sender receives acknowledgement for sent packets, the window moves to the right. For this reason, GBN is referred to as a "sliding window protocol".

Below is what the sender and receiver each do:


Selective Repeat

Another way of implementing pipelining is called selective repeat. It aims to avoid resending packets unnecessarily, as GBN sometimes will. In order to do this, the receiver sends ACKs for each packet individually, whether it is in order or not.

The sender must keep track of the status of each packet in the window individually. If one needs to be resent, it can resend only that one. Hence the name "selective repeat".

The sender/receiver operation is outlined below:

What are the trade-offs between the two protocols?


TCP Packets

TCP actually uses sort of a hybrid of these two schemes. Like GBN, it allows the receiver to acknowledge multiple packets at once. However, like SR, it allows the receiver to request the resending of specific packets, in any order.

Below is a diagram of a TCP packet:

The fields are described below:

Copyright © 2019 Ian Finlayson | Licensed under a Creative Commons Attribution 4.0 International License.