13. Transport Layer Protocol - Reliable Data Transfer

TCP Segments

TCP will divide each message into segments - the sequence number for each segment is the index of the first data byte in the segment. In practice, a random sequence number is used for the initial segment’s sequence number.

The receiver’s ACK message contains the index of the largest byte received: the segment’s sequence number plus the number of data bytes.

TCP uses a single retransmission timer.

Simplified TCP sender (without refinements below):

next_sequence_number = initial_sequence_number
send_base = initial_sequence_number
while True:
  if # data received from upper layer:
    segment = create_tcp_segment(next_sequence_number)
    if timer is None: # no unacknowledged segments in the window
      timer = start_timer()
    send_packet(segment)
    next_sequence_number += len(segment.data)

  elif # timer expired:
    # re-send the segment with the oldest sequence number 
    segment = unacknowledged_packets_in_window()[0]
    send_packet(segment)
    timer = start_timer()

  elif # ack received:
    ack = get_sequence_number()
    if ack > send_base:
      send_base = ack # cumulative ACK
      if len(unacknowledged_packets_in_window()) != 0:
        timer = start_timer()

Some refinements:

Events on the receiver side:

TCP is a mixture of the go-back-N and selective repeat strategies:

Setting the Timeout Value

The timeout value should be longer than the round-trip time, so the first step is to find this value.

The SampleRTT will be the time from segment transmission to ACK, with the condition that retransmissions should not be used - the ACK for the first transmission could arrive after the sender retransmits, giving a wrong value.

The RTT varies over time, so several samples are required. This is done using exponential weighted moving average, which puts more weights on more recent samples:

EstimatedRTT=(1α)EstimatedRTT+αSampleRTTEstimatedRTT = (1 - \alpha) \cdot EstimatedRTT + \alpha \cdot SampleRTT, where α\alpha is typically a value such as 0.1250.125.

An estimate of the variability is also required:

DevRTT=(1β)DevRTT+βSampleRTTEstimatedRTTDevRTT = (1 - \beta) \cdot DevRTT + \beta \cdot |SampleRTT - EstimatedRTT|, where β\beta is typically a value such as 0.250.25.

With these two values, the timeout interval can be calculated:

TimeoutInterval=EstimatedRTT+4DevRTTTimeoutInterval = EstimatedRTT + 4 \cdot DevRTT