linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
Intro
Lessons
Footer
linuxlab-TutorialsPricingAboutPrivacy & cookies
Copyright © 2026 LinuxLab. All rights reserved.
linuxlab.io
Tutorials▾
  • Linux & networking
    File system, processes, TCP/IP, BGP and OSPF
    →
  • Terraform & IaC
    HCL, state, plan/apply on a LocalStack sandbox
    →
  • Git & GitHub
    Object model, plumbing, branching, GitHub Actions
    →
All tutorials →
PricingAboutSign inCreate account
/
  • Introduction
  • Lessons
  • How it works
  • Simulator
  • Knowledge base
  • Interview prep
home/linux/how/tcp-handshake

how/network

The life cycle of a TCP connection

Three-way handshake, then data, then four-way close. Why three handshakes, and why `ss` shows so many states after a connection closes.

TCP is a conversation with acknowledgments. Before they start exchanging data, the two sides have to "agree": each one picks its own random "starting number", and each one has to confirm that it saw the other's. This takes three packets, and that is the famous three-way handshake.

After the handshake, data flows freely. When the sides want to finish, they "say goodbye" separately in both directions (TCP is half-duplex on close: one side can say "that's all from me", while the other still has something to send).

Out of all these transitions a state machine is born: on each side the connection passes through a chain of states. You can see them live with ss -tn, and every ESTABLISHED/TIME_WAIT/etc. in the output comes from exactly here.

Press ▶ to walk the whole cycle from the first SYN to the final TIME_WAIT.

step 1/8·00 · the server listens, the client is ready to connect
clientcurl 10.0.0.5:443server:443 nginxCLOSEDLISTENклиент готов открыть соединение, сервер слушает 0.0.0.0:443rfc 793 · полный жизненный цикл tcp-соединения

§ steps

  1. The server opened a listening socket on port 443 (see port). The OS stack knows: "if a packet arrives here, hand it to this application". The server state is LISTEN.

    The client is still in CLOSED, with no sockets open. When the application calls connect(), the stack starts the active handshake.

recap

What to remember:

  • The three-way handshake is not decoration: each side picks a random initial seq and wants to be sure the peer received it. Without this an attacker could inject packets into other people's connections
  • SYN_SENT stuck forever = the server is not answering (a firewall drops it, or the port is closed). SYN_RECEIVED stuck forever on the server = the incoming connection queue is full
  • The close is four-way because TCP is half-duplex with respect to close: one side can finish sending but still keep receiving data
  • TIME_WAIT is normal. After a close the connection lingers for ~60-120 seconds so that late packets from the old connection do not slip into a new one on the same port. A lot of TIME_WAIT in ss is the trace of heavy downloading, not a leak
  • Any packet with the RST flag instantly closes the connection in both directions. This is a "hard reset", usually from an error on the server side

If you want to watch the states by hand, there is [[tcp-states|an article about all the states]] and a lab on tcp-handshake with tcpdump.

§ dig into the knowledge base

  • tcp-handshakeTCP handshake: the extended article
  • tcp-statesTCP states: all 11 states in detail
  • portport: which ports take part in a connection
  • tls-handshakeTLS handshake: what is built on top of TCP

§ try it hands-on

  • ›intermediate-02-tcp-handshake- TCP handshake: watch it with tcpdump
Footer
linuxlab-
Copyright © 2026 LinuxLab. All rights reserved.
Tutorials
Pricing
About
Privacy & cookies