TCP only acts on the packets it receives, it doesn't know which packets are on the line.
If both sides sends data at the same time, from TCP's perspective, it will send data, then receive data, and after that it receives a packet containing an ACK
Example from the perspective of side A:
A -> B: SEQ=1000 SYN=1000 (SYN is a random value in practice)
A <- B: SEQ=0 ACK=1001 SYN=0 (SYN is a random value in practice)
A -> B: SEQ=1001 ACK=1 (When the packet contains only an ACK,
don't increase the sequence number for
the next packet)
(A knows it sending sequence number is 1001, and the receiving sequence number is 1)
// Example: Only A sends something
A -> B: SEQ=1001 ACK=1 "hello "
A <- B: SEQ=1 ACK=1007 (We acknowledge that 6 bytes have been received)
// Example: Only A sends multiple things quickly
A -> B: SEQ=1007 ACK=1 "World"
A -> B: SEQ=1013 ACK=1 "!"
A <- B: SEQ=1 ACK=1013
A <- B: SEQ=1 ACK=1014
// Example: Both sides send data at the same time
A -> B: SEQ=1014 ACK=1 "Ping!"
A <- B: SEQ=1 ACK=1014 "Hello"
A -> B: SEQ=1019 ACK=6
A <- B: SEQ=6 ACK=1019
// Example: Both sides send data, but B's data packet takes a
// slow route though the internet
A -> B: SEQ=1019 ACK=6 "1"
# B sends the data, the packet is delayed
# B receives the data from A and sends an (SEQ=7, ACK=1020)
A <- B: SEQ=10 ACK=1020
# A sees that it missed some data, but doesn't respond back. It is
# B's responsibility to detect missing ack's and resend data if needed.
A <- B: SEQ=6 ACK=1019 "Data"
# Out of order packet detected (SEQ/ACK values decremented)
# We already know the other side has acknowledges up to 1020, so we remember that value
A -> B: SEQ=1020 ACK=10
// Complex example: Multiple packet are lost/reordered
// (packets from a real world traffic capture I did in my own network)
// The remote side is supposed to say "Hello World!"
A -> B: SEQ=1020 ACK=10 "/MOTD"
A <- B: SEQ=10 ACK=1025
A <- B: SEQ=16 ACK=1025 "World!"
# Note how the sequence ID is suddenly bigger
A -> B: SEQ=1025 ACK=10
# We have received everything correctly up to 10, so only send 10 back
A <- B: SEQ=10 ACK=1025 "Hello "
A -> B: SEQ=1025 ACK=22
# Note how the ack number shoots up by 12, even though we only received 6 bytes of data
A <- B: SEQ=16 ACK=1025 "World!"
A -> B: SEQ=1025 ACK=22
# We receive the same data again, we already know about this, and we already processed it. It must alrady be send before the other side received our ACK
Also another question in the same direction, I read that TCP is an SWP
(Sliding window protocol), I would like to know how ACKs are formed in
this case. TCP is responding with the number of bytes basically as a
Seq number, I can't really imagine how that can happen inside a window
(where you can receive in any order). Is the implementation using two
sets of seq numbers and two windows for both receiver and sender?
TCP was originally designed for slower networks. The sequence number is a 32-bit number, and rolls over every 4GB of data transferred. This was fine when we were in the dial-up time, as we only had internet speeds in the KB range, but this system fails with modern internet speeds, where it could roll over in seconds. These days we add "timestamps" to packets, which increment slower, and it is used in combination with the other fields to handle out of order, duplicate packets and rolled over sequence numbers