Intuitively, it makes more sense that the ACK be the last byte received. Essentially, the receiving end says.

I have received up to N bytes

Then, the sender will receive that ACK that says N and know to send byte N + 1

Instead, the ACK is the last byte received + 1. I don't know the justification for this

2 Answers 2


The sender knows the next segment number it will send, so when the receiver sends an ACK it sends an acknowledgement number of the next expected segment number. If the sender's next segment number is the same as the acknowledgement number, then everything is up to date.

Remember that the receiver may receive segments that are out of order. The sender can send until the receive window is exhausted before it needs to receive an ACK, and the acknowledgement number means the receiver has received all segments prior to the acknowledgement number.

It is defined in RFC 793, transmission Control Protocol:

Acknowledgment Number: 32 bits

If the ACK control bit is set this field contains the value of the next sequence number the sender of the segment is expecting to receive. Once a connection is established this is always sent.


3.7. Data Communication

Once the connection is established data is communicated by the exchange of segments. Because segments may be lost due to errors (checksum test failure), or network congestion, TCP uses retransmission (after a timeout) to ensure delivery of every segment. Duplicate segments may arrive due to network or TCP retransmission. As discussed in the section on sequence numbers the TCP performs certain tests on the sequence and acknowledgment numbers in the segments to verify their acceptability.

The sender of data keeps track of the next sequence number to use in the variable SND.NXT. The receiver of data keeps track of the next sequence number to expect in the variable RCV.NXT. The sender of data keeps track of the oldest unacknowledged sequence number in the variable SND.UNA. If the data flow is momentarily idle and all data sent has been acknowledged then the three variables will be equal.

When the sender creates a segment and transmits it the sender advances SND.NXT. When the receiver accepts a segment it advances RCV.NXT and sends an acknowledgment. When the data sender receives an acknowledgment it advances SND.UNA. The extent to which the values of these variables differ is a measure of the delay in the communication. The amount by which the variables are advanced is the length of the data in the segment. Note that once in the ESTABLISHED state all segments must carry current acknowledgment information.


Whether the receiver acknowledges the last received byte (I have received up to x) or the next expected byte (I have received everything before x) provides the exact same information. It's just a matter of convention or definition.

You can actually interpret the sequence number either way, without a difference. However, the synchronization handshake might make more sense intuitively if you interpret it the next expected way.

  • Can you expand on "However, the synchronization handshake might make more sense intuitively if you interpret it the next expected way"? Jun 9 at 5:53
  • 1
    If you see it the last received way, the initial SYN&ACK acknowledges a fictitious transfer that never happened. If you see it the next expected way, the initial SYN&ACK defines the next byte to send. The latter makes more sense to me.
    – Zac67
    Jun 9 at 6:28
  • In the last received way, the SYN&ACK -- the ACK would be 0. Essentially saying, I have received 0 bytes of data. Which is true, kind of? But that's if yo're not using the ghost byte in the example Jun 9 at 7:50
  • 1
    You don't start with 0. The initial sequence number that is SYNed is effectively random - see rfc-editor.org/rfc/rfc793.html#section-3.3
    – Zac67
    Jun 9 at 8:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.