- Home
-
TCP/IP Handshake
TCP/IP 3-Way Handshake Cheatsheet
Comprehensive guide to TCP/IP handshake covering 3-way connection establishment (SYN, SYN-ACK, ACK), 4-way termination, TCP flags, connection states, packet analysis with tcpdump, and troubleshooting common connection issues.
Before diving into packets, ground yourself in the latest VPS insights on our home base and watch real-time latency trends inside the performance dashboard.
When comparing network stacks, explore provider metrics in the benchmark library, shortlist contenders via the VPS comparison tool, and double-check capabilities inside the provider directory.
Free account required
What is TCP Handshake?
TCP (Transmission Control Protocol) uses a three-way handshake to establish a reliable connection between client and server. This process ensures both parties are ready to transmit data and synchronizes sequence numbers for reliable packet delivery.
Table of Contents
3-Way Handshake (Connection Establishment)
The Three Steps
Client sends SYN packet with initial sequence number (ISN) to server
Flags: [SYN], Seq=0, Win=65535
Server acknowledges client's SYN and sends its own SYN with sequence number
Flags: [SYN, ACK], Seq=0, Ack=1, Win=65535
Client acknowledges server's SYN-ACK. Connection is now ESTABLISHED
Flags: [ACK], Seq=1, Ack=1, Win=65535
Sequence Number Synchronization
Both sides exchange Initial Sequence Numbers (ISN) for reliable data transfer:
- Client sends ISN (e.g., Seq=1000)
- Server acknowledges with Ack=1001 and sends its own ISN (e.g., Seq=5000)
- Client acknowledges with Ack=5001
- All future packets will increment these sequence numbers
Example: Web Browser Connection
# Browser (192.168.1.100) connects to Web Server (93.184.216.34:80)
1. Browser → Server: SYN [Seq=0, Win=65535]
2. Server → Browser: SYN-ACK [Seq=0, Ack=1, Win=65535]
3. Browser → Server: ACK [Seq=1, Ack=1]
Connection ESTABLISHED - Ready to send HTTP request
Why Three Steps?
- Reliability: Both sides confirm they can send and receive data
- Sequence Sync: Exchange starting sequence numbers for ordered delivery
- Duplex Check: Verify bidirectional communication works
Visualize every handshake with the packet analysis tools, then benchmark provider latency in the VPS comparison dataset to spot regions that consistently deliver faster SYN/SYN-ACK cycles.
Compare how each state behaves across environments using the packet analysis tools, and align tuning parameters with the Linux networking cheat sheet to keep TCP transitions predictable under load.
4-Way Handshake (Connection Termination)
The Four Steps (Graceful Closure)
Client finished sending data, wants to close connection
Flags: [FIN, ACK], Seq=1001, Ack=5001
Server acknowledges FIN, but may still have data to send
Flags: [ACK], Seq=5001, Ack=1002
Server finished sending data, ready to close
Flags: [FIN, ACK], Seq=5001, Ack=1002
Client acknowledges server's FIN. Connection CLOSED
Flags: [ACK], Seq=1002, Ack=5002
TIME_WAIT State
After sending final ACK, client enters TIME_WAIT for 2×MSL (Maximum Segment Lifetime, typically 60-240 seconds):
- Ensures final ACK is received by server
- Allows delayed packets to expire
- Prevents port reuse conflicts
RST (Reset) - Abrupt Termination
# Immediate connection termination (ungraceful)
Client → Server: RST [Seq=1001]
# No acknowledgment needed, connection immediately closed
# Data in transit may be lost
RST sent when: Invalid packet received, connection refused, or application aborts
Track how often connections linger in TIME_WAIT using the performance dashboard, and feed closure metrics into the network monitoring toolkit so timeout tuning stays data-driven.
TCP Flags Reference
Flag | Name | Purpose | When Used |
---|---|---|---|
SYN | Synchronize | Initiate connection, sync sequence numbers | First packet of handshake |
ACK | Acknowledgment | Acknowledge received data | All packets after handshake |
FIN | Finish | No more data to send, close connection | Graceful connection termination |
RST | Reset | Abort connection immediately | Error or forced closure |
PSH | Push | Push data to application immediately | Interactive data (SSH, telnet) |
URG | Urgent | Process urgent data first | Rarely used (Ctrl+C interrupts) |
ECE | ECN Echo | Explicit Congestion Notification | Network congestion signaling |
CWR | Congestion Window Reduced | Acknowledge ECN signal received | Congestion control |
Common Flag Combinations
[SYN]
- Connection request[SYN, ACK]
- Connection acceptance[ACK]
- Data acknowledgment[PSH, ACK]
- Push data to app[FIN, ACK]
- Graceful close[RST]
- Abort connectionCombine these diagnostics with the Linux hardening guide, and if you hit blockers, reach out via the contact form so we can help interpret complex traces.
TCP Connection States
LISTEN
Server waiting for incoming connections
SYN_SENT
Client sent SYN, waiting for SYN-ACK
SYN_RECEIVED
Server received SYN, sent SYN-ACK, waiting for ACK
ESTABLISHED
Connection open, data transfer in progress
FIN_WAIT_1
Sent FIN, waiting for ACK or FIN
FIN_WAIT_2
Received ACK for FIN, waiting for peer's FIN
CLOSE_WAIT
Received FIN, waiting for application to close
CLOSING
Both sides sent FIN simultaneously
LAST_ACK
Sent FIN, waiting for final ACK
TIME_WAIT
Waiting for delayed packets to expire (2×MSL)
CLOSED
Connection fully terminated
View Current TCP Connections
# Linux/Unix
$ netstat -ant | grep ESTABLISHED
$ ss -tan state established
# View all TCP states
$ netstat -tan
$ ss -tan
# Count connections by state
$ ss -tan | awk '{print $1}' | sort | uniq -c
Packet Analysis Tools
Capture TCP Handshake with tcpdump
# Capture SYN packets
$ sudo tcpdump -i eth0 'tcp[tcpflags] & tcp-syn != 0'
# Capture full 3-way handshake to specific host
$ sudo tcpdump -i eth0 -nn 'host 93.184.216.34 and (tcp-syn or tcp-ack)'
# Capture handshake with detailed output
$ sudo tcpdump -i eth0 -nn -vv 'tcp[tcpflags] & (tcp-syn|tcp-fin) != 0'
# Save to file for Wireshark analysis
$ sudo tcpdump -i eth0 -w handshake.pcap 'tcp port 80'
Filter Specific TCP Flags
# SYN packets only
$ sudo tcpdump 'tcp[tcpflags] == tcp-syn'
# SYN-ACK packets
$ sudo tcpdump 'tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)'
# FIN packets
$ sudo tcpdump 'tcp[tcpflags] & tcp-fin != 0'
# RST packets (connection resets)
$ sudo tcpdump 'tcp[tcpflags] & tcp-rst != 0'
Wireshark Display Filters
# Show only handshake packets
tcp.flags.syn==1 || tcp.flags.fin==1
# Connection establishment
tcp.flags.syn==1 && tcp.flags.ack==0
# Server responses
tcp.flags.syn==1 && tcp.flags.ack==1
# Connection termination
tcp.flags.fin==1
# Connection resets
tcp.flags.reset==1
# Specific conversation
tcp.stream eq 0
Example: Capture Web Connection
$ sudo tcpdump -i eth0 -nn 'tcp port 80' -c 10
14:30:15.123456 IP 192.168.1.100.54321 > 93.184.216.34.80: Flags [S], seq 1000, win 65535
14:30:15.145678 IP 93.184.216.34.80 > 192.168.1.100.54321: Flags [S.], seq 5000, ack 1001, win 65535
14:30:15.145789 IP 192.168.1.100.54321 > 93.184.216.34.80: Flags [.], ack 5001, win 65535
# Connection ESTABLISHED - HTTP request follows
Analyze Connection Timing
# Measure handshake completion time
$ sudo tcpdump -i eth0 -ttt 'tcp port 443 and host example.com'
# Results show delta time between packets:
00:00:00.000000 - SYN sent
00:00:00.025000 - SYN-ACK received (25ms RTT)
00:00:00.000100 - ACK sent
# Total handshake: ~25ms
Need more capture tricks? Pair this guide with the IP command reference, and feed packet metrics into the latency benchmarks to validate performance after each change.
Troubleshooting & Best Practices
Common Issues
Symptoms: SYN sent, no SYN-ACK received
Causes: Firewall blocking, wrong IP/port, server down, routing issues
$ telnet example.com 80
$ nc -vz example.com 80
Symptoms: SYN sent, RST received immediately
Causes: No service listening on port, firewall reset
$ netstat -tuln | grep :80
$ ss -tuln | grep :80
Symptoms: Stuck in SYN_RECV state
Causes: SYN flood attack, packet loss, client crash
$ netstat -tan | grep SYN_RECV | wc -l
Symptoms: Port exhaustion, "Address already in use"
Solution: Enable TCP reuse (carefully)
# Linux kernel tuning (use with caution)
$ sudo sysctl -w net.ipv4.tcp_tw_reuse=1
Best Practices
- Set appropriate timeouts: Avoid hanging connections with proper SO_RCVTIMEO and SO_SNDTIMEO
- Use TCP keepalive: Detect dead connections with SO_KEEPALIVE
- Enable TCP Fast Open (TFO): Reduce handshake latency for repeated connections
- Monitor connection states: Watch for excessive SYN_RECV (possible attack) or TIME_WAIT (port exhaustion)
- Tune SYN backlog: Increase net.ipv4.tcp_max_syn_backlog for high-traffic servers
- Enable SYN cookies: Protect against SYN flood attacks with net.ipv4.tcp_syncookies=1
- Use connection pooling: Reuse connections instead of opening new ones repeatedly
Testing Tools
# Test connection establishment
$ telnet example.com 80
$ nc -vz example.com 80
# Monitor handshake in real-time
$ sudo tcpdump -i any -nn 'tcp[tcpflags] & tcp-syn != 0' &
$ curl http://example.com
# Simulate SYN flood (testing only!)
$ sudo hping3 -S -p 80 --flood target.com
# Check server's SYN queue
$ netstat -an | grep SYN_RECV | wc -l
Master Network Performance & Connectivity
Understanding TCP/IP is crucial for optimizing server performance. Check our VPS benchmarks to find providers with optimal network latency and connection handling for your applications.
Curious about our methodology? Meet the team on the About page, and if you need help dissecting captures, reach out via the contact form. Capturing real user data? Review the guardrails in our privacy policy first.
Keep tuning handshake performance with real-time metrics on the performance dashboard, and pair this guide with the Linux networking cheat sheet plus the IP command reference for deeper troubleshooting.