| 1 | Source port number (TCP service ID for sender of this packet) |
|||||||||||||||
| 2 | Destination port number (TCP service ID for receiver of this packet) |
|||||||||||||||
| 3 | TCP sequence number | |||||||||||||||
| 4 | (byte count of data sent by source, starting at random value) | |||||||||||||||
| 5 | Acknowledgment number | |||||||||||||||
| 6 | (this is the sequence number of the last data byte received from destination) | |||||||||||||||
| 7 | TCP header length (offset data, in 32-bit words) |
Reserved (6 bits in length) |
TCP option bit flags | |||||||||||||
| 8 | Current TCP window size (amount of data sender is willing to accept in bytes) |
|||||||||||||||
| 9 | Checksum | |||||||||||||||
| 10 | Urgent data pointer (byte offset into data to last urgent data byte) |
|||||||||||||||
| 11 | Options and padding (length varies, to calculate: (TCP header length - 5) * 4 bytes ) |
|||||||||||||||
| URG | ACK | PSH | RST | SYN | FIN |
|
|
| Variable | Initial value | Formula to recompute |
|---|---|---|
| SampleRTT | The sample RTT for a segment is the amount of time from when the segment is sent (that is, passed to IP) until an ACK for the segment is received. | |
| EstimatedRTT | 1000 ms | EstimatedRTT = (1-a).EstimatedRTT + a.SampleRtt |
| DevRTT | SampleRTT/2 | DevRTT = (1-b).DevRTT + b.|SampleRTT-EstimatedRTT| |
| TimeoutInterval | 3000 ms | TimeoutInterval = EstimatedRTT + 4.DevRTT |
The recommended values for a and b are:
There are modifications that most TCP implementation deploys. The first concerns the length of the timeout interval after a timer expiration. In this modification, whenever the timeout event occurs, TCP retransmits the not-yet-acknowledged segment with the smallest sequence number, but each time TCP retransmits, it sets the timeout interval to twice the previous value. However, whenever the timer is started after either of the two other events (ACK or data replication), the timeout interval is derived from the most recent values of EstimatedRTT and DevRTT.
All details about TCP timer can be found in the Official Documentation. This page shows how this actually works (you can find Excel source here).
NextSeqNum = InitialSeqNum;
SendBase = InitialSeqNum;
loop( forever ){
switch( event ){
event: data received from application above
create TCP segment with sequence number NextSeqNum
if( timer currently not running )
start timer
pass segment to IP
NextSeqNum = nextSeqNum + length(data)
break;
event: timer timeout
retransmit not-yet-acknowledged segment with smallest sequence number
start timer
break;
event: ACK received, with ACK value AckNum
if( AckNum > SendBase ){
SendBase = AckNum
if( there are currently any not-yet-acknowledged segmenta )
start timer
}
break;
}
}
| Event | TCP Receiver Action |
| Arrival of in-order segment with expected sequence number. All data up to expected sequence number already acknowledged. | Delayed ACK. Wait for 500ms for arrival of another in-order segment. If next in-order segment does not arrive in this interval, send an ACK |
| Arrival of in-order segment with expected sequence number. One other in-order segment waiting for ACK transmission. | Immediately send single cumulative ACK, ACKing both in-order segments. |
| Arrival of out-of-order segment with higher-than-expected sequence number. | Immediately send duplicate ACK, indicating sequence number of the next expected byte (which is the lower end of the gap). |
| Arrival of a segment that partially or completely fills gap in received data. | Immediately send ACK, provided that segment starts at the lower end of the gap. |
Fast Retransmit version:
NextSeqNum = InitialSeqNum;
SendBase = InitialSeqNum;
loop( forever ){
switch( event ){
event: data received from application above
create TCP segment with sequence number NextSeqNum
if( timer currently not running )
start timer
pass segment to IP
NextSeqNum = nextSeqNum + length(data)
break;
event: timer timeout
retransmit not-yet-acknowledged segment with smallest sequence number
start timer
break;
event: ACK received, with ACK value AckNum
if( AckNum > SendBase ){
SendBase = AckNum
if( there are currently any not-yet-acknowledged segmenta )
start timer
}
else{ /* a duplicate ACK for already acknowledged segment */
increment number of duplicate ACKs received for AckNum
if( number of duplicate ACKs received for AckNum == 3 ){
/* TCP fast retransmission */
resend segment with sequence number AckNum
}
}
break;
}
}
Q: How are the sequence numbers chosen?
A: In most Berkley-derived implementations, when system is initialized the initial sequence
number is set to 1. It then incremented by 64,000 every half-second, and will cycle back to 0 about
every 9.5 hours. Additionally, each time a connection is established, this variable is incremented by
64,000.
| End of option list: | kind=0 | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| No operation: | kind=1 | |||||||||
| Maximum segment size: | kind=2 | len=4 | MSS | |||||||
| Window scale factor: | kind=3 | len=3 | shift count |
|||||||
| Timestamp: | kind=8 | len=10 | timestamp value | timestamp echo reply | ||||||
Please refer to RFC 793 for additional information.