Baud
All protocols

TCP

A reliable byte stream built from numbered segments and acknowledgements.

The header of a SYN

The first segment of every TCP connection, field by field. Watch the flag byte: eight switches, one of which is on.

TCP SYN segment · 24 bytes048121620C811001000220010001000000000005001010000000000000000000000000300000011E811101000000000000000000000000000000000000000000060011000000200000010FA11111010F011110000D211010010EB1110101100000000000000000000020000001004000001000500000101B410110100Source portDestination portSequence numberAcknowledgment numberData o…Reserv…FlagsWindow sizeChecksumUrgent pointerOption kindOption lengthMSS valueClick a field to inspect it

Whole frame

C8 22 00 50 00 00 03 E8 00 00 00 00 60 02 FA F0 D2 EB 00 00 02 04 05 B4: a request to open a connection from port 51234 to port 80, starting at sequence 1000, willing to receive 1460-byte segments.

FieldOffsetExample valueMeaning
Source portByte 0–10xC822 = 51234The client's ephemeral port. Together with both IP addresses and the destination port it identifies this connection: the 4-tuple.
Destination portByte 2–30x0050 = 80 (HTTP)The service being contacted. 80 is HTTP (443 would be HTTPS, 22 SSH, 25 SMTP).
Sequence numberByte 4–71000 (ISN)Every byte sent gets a number. In a SYN this field carries the Initial Sequence Number (ISN) the sender will count from. The SYN itself consumes one number, so the first data byte will be ISN + 1. Real stacks pick a random ISN; 1000 is used here for readability.
Acknowledgment numberByte 8–110 (unused, ACK flag off)'I have received everything up to here; send me this byte next.' Meaningless in a first SYN, so it is 0 and the ACK flag stays off.
Data offsetByte 12, bits 7–46 words = 24 bytesHeader length in 32-bit words, so the receiver knows where the data starts. 6 × 4 = 24 bytes: the 20-byte base header plus 4 bytes of options.
ReservedByte 12, bits 3–00Reserved for future use, sent as 0.
FlagsByte 130x02 = SYNEight one-bit switches that say what kind of segment this is. A SYN has only SYN set.
Window sizeByte 14–150xFAF0 = 64240Flow control: how many more bytes I can buffer. The sender must not have more than this many unacknowledged bytes in flight.
ChecksumByte 16–170xD2EB (✓)Covers a pseudo-header (source and destination IP, protocol 6, TCP length), the header and the data. Computed for real here: 0xD2EB. Mandatory, unlike UDP in IPv4.
Urgent pointerByte 18–190Only meaningful when URG is set. Practically unused.
Option kindByte 202 = MSSOptions come as kind, length, value. Kind 2 = Maximum Segment Size.
Option lengthByte 214The whole option is 4 bytes (kind, length, 2 value bytes).
MSS valueByte 22–230x05B4 = 1460'The largest TCP payload I can take in one segment': 1460 = 1500-byte Ethernet MTU minus 20 (IP) minus 20 (TCP).

Overview

IP may drop, duplicate and reorder packets. TCP hides that: it numbers every byte, makes the receiver acknowledge what arrived, retransmits what did not, and reassembles the stream in order. The application just sees a pipe that delivers bytes reliably.

A connection starts with a three-way handshake and ends with FINs. In between, the window size (flow control) and the congestion window (congestion control) decide how fast the sender may go.

Key facts

Header
20 bytes (up to 60)
IP protocol number
6
Delivery
Reliable, ordered
Connection
3-way handshake, 4-way close
Identified by
(src IP, src port, dst IP, dst port)
Standard
RFC 9293

Opening a connection

Three segments set up the connection, then data and its acknowledgement. Follow the sequence numbers.

Client192.168.1.20:51234Server203.0.113.50:80SYNseq=1000SYN, ACKseq=5000 ack=1001ACKseq=1001 ack=5001PSH, ACKseq=1001 ack=5001 len=100ACKseq=5001 ack=1101CLOSEDLISTENSYN_SENTSYN_RCVDESTABLISHEDESTABLISHED

Whole exchange

Three segments to open, then every byte is numbered and every segment is acknowledged. That bookkeeping is what turns an unreliable packet network into a reliable byte stream.

  1. 11. SYN: shall we talk?

    The client picks an initial sequence number (1000) and asks to open a connection. The server is already listening on port 80.

  2. 22. SYN-ACK: yes, and here is mine

    The server acknowledges 1001 (the SYN used up number 1000, so it expects 1001 next) and announces its own initial sequence number, 5000. One segment does both jobs.

  3. 33. ACK: connection open

    The client acknowledges 5001. Both sides now know the other's starting number and that the other can hear them. The connection is established; data may flow in both directions.

  4. 4First data: an HTTP request

    The client sends 100 bytes (say an HTTP GET). They occupy sequence numbers 1001 to 1100. PSH asks the server to hand them to the application immediately.

  5. 5ACK: got all 100 bytes

    ack=1101 means 'everything up to 1100 has arrived, send 1101 next'. If this ACK never came, the client would retransmit the data after a timeout.

Closing a connection

Four segments, because each direction closes on its own.

Client192.168.1.20:51234Server203.0.113.50:80FIN, ACKseq=1101 ack=5001ACKseq=5001 ack=1102FIN, ACKseq=5001 ack=1102ACKseq=1102 ack=5002ESTABLISHEDESTABLISHEDFIN_WAIT_1CLOSE_WAITFIN_WAIT_2LAST_ACKTIME_WAITCLOSED

Whole exchange

FIN, ACK, FIN, ACK: each direction is closed on its own. TIME_WAIT keeps the client's port reserved a little longer so stray late packets from this connection cannot confuse the next one.

  1. 11. FIN: I am done sending

    The client has no more data and says so. FIN uses up one sequence number. The client may still receive.

  2. 22. ACK: understood

    The server acknowledges the FIN. The client's half of the connection is closed; the server's half is still open and may keep sending.

  3. 33. FIN: now I am done too

    When the server's application has closed its socket, the server sends its own FIN. Closing is two independent one-way shutdowns, which is why it takes four segments.

  4. 44. ACK: goodbye

    The client acknowledges the server's FIN. The server closes immediately; the client waits in TIME_WAIT (about 60 s, twice the maximum segment lifetime) in case this ACK is lost and the server resends its FIN.

Where you meet it

  • HTTP/1.1 and HTTP/2, HTTPS (with TLS), SSH, SMTP, databases
  • Anything where losing or reordering bytes is unacceptable
  • Not for real-time media: a lost segment stalls everything behind it (head-of-line blocking)

Watch out for

  • Sequence numbers count bytes, not segments, and SYN and FIN each consume one number even though they carry no data.
  • Wireshark shows relative sequence numbers by default; the real ISN is a random 32-bit value.
  • A SYN with no SYN-ACK is the signature of a firewall drop or a dead host. A RST in reply means the port is closed.
  • Many 'slow' connections are really lost segments waiting for a retransmission timeout.

Standards

  • RFC 9293: Transmission Control Protocol
  • RFC 1071: Internet Checksum

Related protocols