Which TCP states do the client and the server pass through while a connection opens, and when can each side first send data?
answer
- active open versus passive open
- LISTEN belongs to the server
- SYN-RECEIVED waits for the final ACK
- count round trips from the client's SYN
basics
~20 sThe client goes CLOSED, SYN-SENT, ESTABLISHED; the server goes LISTEN, SYN-RECEIVED, ESTABLISHED. The client is established one round trip after its SYN and can send then; the server is established about half a round trip later.
solid answer
~50 sThe server does a *passive open* and waits in `LISTEN`. The client does an *active open*: it sends a `SYN` and enters `SYN-SENT`. On receiving that SYN the server replies with a `SYN-ACK` and moves to `SYN-RECEIVED`. When the SYN-ACK arrives, the client sends the final `ACK` and enters `ESTABLISHED`; the server enters `ESTABLISHED` when that ACK arrives. So the client may send data one round trip after its SYN, its first request reaches the server after about 1.5 round trips, and the reply is back after two, one round trip more than on an already open connection. In the base protocol, a server asked to send while in `SYN-RECEIVED` queues the data until it is `ESTABLISHED`. If a SYN is lost, the retry waits for the initial retransmission timeout, 1 second under RFC 6298, which dwarfs the handshake on most paths.
go deeper
Name the states on each side in order: client CLOSED, SYN-SENT, ESTABLISHED; server LISTEN, SYN-RECEIVED, ESTABLISHED. Know that LISTEN is a server state.
Walk through which segment triggers each transition, show that the two ends become established half a round trip apart, and count the two round trips before a first reply on a fresh connection.
Read connect-latency symptoms from the state machine: recognise one-second and three-second steps as lost handshake segments recovered by the initial RTO, and explain why a lost final ACK rarely matters.
Weigh the round trip every fresh connection pays against the cost of keeping connections open, and set expectations for latency budgets on paths with long round-trip times.
## The states involved in opening RFC 9293 lists the TCP connection states as `LISTEN`, `SYN-SENT`, `SYN-RECEIVED`, `ESTABLISHED`, `FIN-WAIT-1`, `FIN-WAIT-2`, `CLOSE-WAIT`, `CLOSING`, `LAST-ACK`, `TIME-WAIT` and the **fictional** state `CLOSED`, fictional because it stands for having no connection record (no TCB) at all. Opening a connection uses the first four plus `CLOSED`. | State | Normally held by | Meaning | Left when | |---|---|---|---| | `CLOSED` | both | no connection record exists | the application opens | | `LISTEN` | server | waiting for a connection request from any remote peer and port | a SYN arrives | | `SYN-SENT` | client | sent a SYN, waiting for a matching connection request | a SYN-ACK arrives | | `SYN-RECEIVED` | server | received a SYN and sent one, waiting for the acknowledgment of its own SYN | an acceptable ACK arrives | | `ESTABLISHED` | both | open; data flows both ways | teardown begins | The two sides take **different paths**. The client never passes through `LISTEN`, and in an ordinary open the server never passes through `SYN-SENT`. (Only a *simultaneous open*, where both ends actively open toward each other, sends both ends through `SYN-SENT` and then `SYN-RECEIVED`.) ## The transitions, step by step 1. **Server, passive open:** `CLOSED` to `LISTEN`. Nothing is sent. 2. **Client, active open:** sends `SYN` with its ISN *x*, moves to `SYN-SENT`. 3. **Server receives the SYN in `LISTEN`:** records the client's ISN, picks its own ISN *y*, sends `SYN-ACK` (sequence *y*, acknowledgment *x+1*), moves to `SYN-RECEIVED`. 4. **Client receives the SYN-ACK:** it acknowledges the client's SYN, so the client sends `ACK` (acknowledgment *y+1*) and moves to `ESTABLISHED`. 5. **Server receives that ACK:** RFC 9293 checks that it acknowledges the server's SYN; if so the server moves to `ESTABLISHED`. Two consequences are easy to miss: - The ends reach `ESTABLISHED` **at different times**, half a round trip apart. - In the base protocol, a server application that tries to send while its side is still `SYN-RECEIVED` has its data queued; RFC 9293 transmits it only after `ESTABLISHED` is reached. ## Counting connect latency Measured in round-trip times (RTT) from the moment the client sends its SYN, and ignoring server processing time: | Time | Event | |---|---| | 0 | client sends SYN, enters `SYN-SENT` | | 0.5 RTT | server receives SYN, sends SYN-ACK, enters `SYN-RECEIVED` | | 1 RTT | client receives SYN-ACK, enters `ESTABLISHED`, sends ACK and its request | | 1.5 RTT | server receives ACK and request, enters `ESTABLISHED` | | 2 RTT | client receives the reply | So, without extensions such as Fast Open, a request-reply exchange on a **fresh** TCP connection needs at least two round trips, against one on a connection that is already open. With an 80 ms round trip, that is at least 160 ms before the first reply byte, of which 80 ms is the handshake. Any encryption handshake layered on top adds its own round trips; what a new HTTPS connection costs in total belongs to the HTTP connection topic. ## When the handshake itself is slow - **Lost SYN or SYN-ACK.** No round-trip measurement exists yet, so recovery waits for the *initial* retransmission timeout. RFC 6298 says it SHOULD be 1 second (the RFC it replaced used 3 seconds), doubling on each retry. RFC 6298 also says that if a SYN's timer expired and the RTO in use was below 3 seconds, the RTO MUST be reset to 3 seconds when data transmission begins. - **Lost final ACK.** Usually harmless. Every segment the client sends after the SYN carries the ACK flag, so its first data segment completes the server's side of the handshake when it arrives. If the client sends nothing, the server's SYN-ACK retransmission timer recovers the exchange. - **The signature.** Connect times that cluster around one and three seconds above normal point to a lost handshake segment recovered by timeout, not to a slow server. How the retransmission timeout is computed once samples exist is the retransmission topic; here it only matters that the handshake starts with no sample and therefore with a large, conservative timer.
- What happens if the client's final ACK of the TCP handshake is lost but the client immediately sends a request?Nothing breaks. Every segment the client sends after its SYN carries the ACK flag and acknowledges the server's SYN, so the request segment completes the handshake: the server in SYN-RECEIVED sees an acceptable acknowledgment, moves to ESTABLISHED and processes the data. Only if the client sends nothing must the server rely on retransmitting its SYN-ACK.
- Why do TCP connect times on an otherwise healthy path sometimes cluster about one and three seconds above normal?A lost SYN or SYN-ACK is recovered only by timeout, and before any round-trip sample exists the timer is the initial RTO: RFC 6298 recommends 1 second (its predecessor used 3), doubling per retry. One lost handshake segment adds about one second and two add about three, a pattern distinct from ordinary round-trip variation.
saying these in an interview costs you the question
- The client passes through LISTEN before it sends its SYN.
- Both ends enter ESTABLISHED at the same instant.
- The server enters ESTABLISHED as soon as it sends its SYN-ACK.
- The client may send its request as soon as its SYN has left.
- A lost final ACK leaves the connection stuck until that exact ACK is resent.