Overview
The Transmission Control Protocol (TCP) provides reliable, ordered, and error-checked delivery of data between applications running on networked computers. TCP operates at the transport layer of the Internet protocol suite and forms the foundation for most application-layer protocols including HTTP, SMTP, FTP, and SSH.
TCP emerged from ARPANET research in the 1970s. The protocol splits application data into segments, adds sequencing information, manages retransmission of lost packets, and ensures data arrives in the correct order. Unlike UDP which offers unreliable datagram delivery, TCP guarantees that data sent from one endpoint arrives intact at the destination.
The protocol operates through a connection-oriented model. Before data transmission begins, TCP establishes a connection through a three-way handshake. During active transmission, TCP monitors packet delivery, maintains flow control to prevent overwhelming the receiver, and implements congestion control to respond to network conditions. When communication completes, TCP terminates the connection through a four-way handshake.
TCP connections occur between two endpoints identified by IP addresses and port numbers. A socket pair (source IP, source port, destination IP, destination port) uniquely identifies each TCP connection. The protocol uses sequence numbers to track bytes sent and acknowledgment numbers to confirm receipt. TCP headers include control flags (SYN, ACK, FIN, RST, PSH, URG) that coordinate connection management and data delivery.
Applications interact with TCP through socket APIs. The operating system kernel implements the TCP protocol stack, handling packet segmentation, acknowledgment tracking, retransmission timers, and window management. Applications write data to sockets and read data from sockets without managing the underlying protocol complexity.
TCP provides several key services to applications: reliable delivery through acknowledgments and retransmissions, ordered delivery through sequence numbers, flow control through sliding windows, congestion control through algorithms like Slow Start and Congestion Avoidance, and full-duplex communication allowing simultaneous bidirectional data transfer.
Key Principles
TCP operates as a stateful, connection-oriented protocol. Each connection maintains state information including sequence numbers, acknowledgment numbers, window sizes, round-trip time estimates, and retransmission timer values. This state management enables the reliability guarantees TCP provides.
Connection Establishment
TCP establishes connections through a three-way handshake:
- Client sends SYN segment with initial sequence number (ISN)
- Server responds with SYN-ACK segment containing its own ISN and acknowledging client's ISN
- Client sends ACK segment acknowledging server's ISN
This handshake synchronizes sequence numbers and establishes initial window sizes. The initial sequence numbers prevent confusion from delayed packets belonging to previous connections between the same endpoints.
Client Server
| |
|----SYN (seq=x)--------->|
| |
|<---SYN-ACK (seq=y)------|
| (ack=x+1) |
| |
|----ACK (ack=y+1)------->|
| |
Sequence Numbers and Acknowledgments
TCP assigns a sequence number to each byte of data. The sequence number in a TCP segment indicates the position of the first data byte in that segment. Acknowledgment numbers indicate the next expected sequence number, confirming receipt of all bytes up to that point.
Cumulative acknowledgments confirm receipt of all data up to a specific sequence number. If segments arrive out of order, TCP buffers them until missing segments arrive. Selective acknowledgments (SACK) allow receivers to acknowledge non-contiguous blocks of data, enabling more efficient retransmission of specific lost segments.
Reliability Through Retransmission
TCP retransmits segments when acknowledgments don't arrive within the retransmission timeout (RTO). The RTO calculation considers the measured round-trip time (RTT) and its variation. TCP samples RTT continuously and adjusts RTO using smoothed round-trip time (SRTT) and round-trip time variation (RTTVAR):
SRTT = (1 - α) × SRTT + α × RTT_sample
RTTVAR = (1 - β) × RTTVAR + β × |SRTT - RTT_sample|
RTO = SRTT + max(G, 4 × RTTVAR)
Where α = 1/8, β = 1/4, and G represents the clock granularity.
Flow Control
TCP implements sliding window flow control to prevent fast senders from overwhelming slow receivers. Each ACK segment includes a window size indicating how much data the receiver can accept. The sender limits unacknowledged data to the receiver's advertised window.
The window slides forward as the receiver processes data and sends acknowledgments with updated window sizes. Window scaling extends the maximum window size beyond 65,535 bytes for high-bandwidth networks.
Congestion Control
TCP adjusts transmission rates in response to network congestion. The congestion window (cwnd) limits how much unacknowledged data the sender can transmit. The effective transmission window equals the minimum of the congestion window and the receiver's advertised window.
TCP implements several congestion control phases:
Slow Start: Begins with cwnd = 1 MSS (Maximum Segment Size). Each ACK increases cwnd by 1 MSS, causing exponential growth until reaching the slow start threshold (ssthresh).
Congestion Avoidance: Once cwnd reaches ssthresh, growth becomes linear. Each RTT increases cwnd by approximately 1 MSS.
Fast Retransmit: When receiving three duplicate ACKs, TCP retransmits the missing segment without waiting for timeout.
Fast Recovery: After fast retransmit, TCP reduces ssthresh to half of cwnd, sets cwnd to ssthresh plus 3 MSS, and continues with congestion avoidance.
Connection Termination
TCP connections terminate through a four-way handshake allowing independent closure of each direction:
- Active closer sends FIN segment
- Passive closer acknowledges with ACK
- Passive closer sends its own FIN when ready to close
- Active closer acknowledges with ACK
The connection enters TIME_WAIT state after final ACK, lasting 2 × MSL (Maximum Segment Lifetime) to ensure final ACK arrives and prevent delayed segments from confusing future connections.
Ruby Implementation
Ruby provides TCP networking through the Socket library in the standard library. The TCPServer and TCPSocket classes offer higher-level abstractions over raw sockets for common TCP server and client patterns.
Basic TCP Client
require 'socket'
# Connect to server
socket = TCPSocket.new('example.com', 80)
# Send HTTP request
socket.puts "GET / HTTP/1.1"
socket.puts "Host: example.com"
socket.puts "Connection: close"
socket.puts ""
# Read response
response = socket.read
puts response
socket.close
The TCPSocket constructor performs DNS resolution and establishes the TCP connection, handling the three-way handshake automatically. The socket acts as an IO object supporting standard read and write operations.
TCP Server Implementation
require 'socket'
server = TCPServer.new(8080)
puts "Server listening on port 8080"
loop do
# Accept blocks until client connects
client = server.accept
# Read client request
request = client.gets
puts "Received: #{request}"
# Send response
client.puts "HTTP/1.1 200 OK"
client.puts "Content-Type: text/plain"
client.puts "Connection: close"
client.puts ""
client.puts "Hello from TCP server"
client.close
end
TCPServer.accept blocks until a client connects, returning a socket for that specific connection. Each accepted connection gets its own socket instance, allowing concurrent handling of multiple clients.
Multi-threaded TCP Server
require 'socket'
server = TCPServer.new(8080)
puts "Multi-threaded server listening on port 8080"
loop do
Thread.start(server.accept) do |client|
begin
request = client.gets
# Process request
response = process_request(request)
client.puts response
rescue => e
puts "Error handling client: #{e.message}"
ensure
client.close
end
end
end
def process_request(request)
# Request processing logic
"Processed: #{request}"
end
Threading enables concurrent client handling. Each connection runs in its own thread, preventing slow clients from blocking other connections. The ensure block guarantees socket cleanup even when errors occur.
Non-blocking TCP Operations
require 'socket'
socket = TCPSocket.new('example.com', 80)
# Make socket non-blocking
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
begin
# Non-blocking write
socket.write_nonblock("GET / HTTP/1.1\r\n\r\n")
rescue IO::WaitWritable
# Socket buffer full, wait for writability
IO.select(nil, [socket])
retry
end
begin
# Non-blocking read
data = socket.read_nonblock(4096)
puts data
rescue IO::WaitReadable
# No data available, wait for readability
IO.select([socket])
retry
rescue EOFError
# Connection closed
puts "Connection closed by server"
end
socket.close
Non-blocking operations return immediately with IO::WaitReadable or IO::WaitWritable exceptions when operations would block. IO.select enables multiplexing multiple sockets efficiently.
Socket Options and Configuration
require 'socket'
socket = TCPSocket.new('example.com', 80)
# Enable TCP keepalive
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
# Set keepalive parameters (Linux)
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE, 60)
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL, 10)
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPCNT, 3)
# Disable Nagle's algorithm
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_NODELAY, 1)
# Set send buffer size
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 65536)
# Set receive buffer size
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVBUF, 65536)
# Get current options
keepalive = socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE)
puts "Keepalive enabled: #{keepalive.bool}"
socket.close
Socket options control TCP behavior. TCP_NODELAY disables Nagle's algorithm, reducing latency for small writes. Buffer sizes affect memory usage and throughput. Keepalive probes detect dead connections.
Handling Connection Timeouts
require 'socket'
require 'timeout'
def connect_with_timeout(host, port, timeout_seconds)
Timeout.timeout(timeout_seconds) do
TCPSocket.new(host, port)
end
rescue Timeout::Error
raise "Connection timeout after #{timeout_seconds} seconds"
end
# Connection with timeout
socket = connect_with_timeout('example.com', 80, 5)
# Read with timeout
begin
Timeout.timeout(10) do
data = socket.read
puts data
end
rescue Timeout::Error
puts "Read operation timed out"
ensure
socket.close if socket
end
Timeout module wraps blocking operations with time limits. This prevents indefinite blocking when servers become unresponsive or network issues occur.
Implementation Approaches
TCP applications follow several architectural patterns depending on requirements for concurrency, scalability, and resource efficiency.
Single-threaded Blocking Server
The simplest server implementation accepts connections sequentially, processing each client completely before accepting the next. This approach uses minimal resources and simple code but cannot handle concurrent clients:
require 'socket'
server = TCPServer.new(8080)
loop do
client = server.accept
handle_client(client)
client.close
end
This pattern works for low-traffic services or testing but creates head-of-line blocking where slow clients delay all subsequent connections.
Thread-per-connection Model
Spawning a thread for each connection enables concurrent client handling. The operating system schedules threads, allowing multiple connections to progress simultaneously:
require 'socket'
server = TCPServer.new(8080)
loop do
client = server.accept
Thread.new(client) do |conn|
handle_client(conn)
conn.close
end
end
This approach scales to hundreds of concurrent connections on modern systems. Thread creation overhead and memory consumption become concerns beyond a few thousand connections. Thread pools limit maximum concurrency and reuse threads to reduce overhead.
Thread Pool Implementation
require 'socket'
require 'thread'
server = TCPServer.new(8080)
queue = Queue.new
# Create worker threads
workers = 10.times.map do
Thread.new do
loop do
client = queue.pop
handle_client(client)
client.close
end
end
end
# Accept connections and queue them
loop do
client = server.accept
queue.push(client)
end
Thread pools bound resource consumption and eliminate thread creation overhead for each connection. Queue depth indicates load, enabling monitoring and load shedding when capacity approaches limits.
Non-blocking IO with Event Loop
Event-driven servers use IO multiplexing to handle many connections in a single thread. IO.select monitors multiple sockets and returns when any become readable or writable:
require 'socket'
server = TCPServer.new(8080)
clients = []
loop do
# Monitor server and all clients
readable, writable = IO.select([server] + clients, clients, nil, 1)
readable&.each do |socket|
if socket == server
# New connection
clients << server.accept
else
# Data available from client
begin
data = socket.read_nonblock(4096)
process_data(socket, data)
rescue EOFError
socket.close
clients.delete(socket)
end
end
end
writable&.each do |socket|
# Socket ready for writing
send_pending_data(socket)
end
end
This pattern scales to tens of thousands of connections with minimal memory overhead. Complexity increases compared to threaded models, particularly when implementing state machines for partial reads and writes.
Reactor Pattern
The Reactor pattern structures event-driven servers with separation between event detection and event handling:
class Reactor
def initialize
@handlers = {}
@running = true
end
def register(socket, handler)
@handlers[socket] = handler
end
def unregister(socket)
@handlers.delete(socket)
end
def run
while @running
readable = @handlers.keys
ready_sockets = IO.select(readable, nil, nil, 1)
ready_sockets&.first&.each do |socket|
handler = @handlers[socket]
handler.handle_read(socket)
end
end
end
def stop
@running = false
end
end
class ClientHandler
def handle_read(socket)
data = socket.read_nonblock(4096)
process(data)
socket.write("Response\n")
rescue EOFError
socket.close
end
def process(data)
# Application logic
end
end
Reactors decouple event monitoring from business logic. Handlers encapsulate connection-specific behavior, improving code organization for complex protocols.
Hybrid Threading and Event Models
Modern servers often combine threading and event-driven approaches. Multiple threads each run event loops, distributing connections across threads:
require 'socket'
server = TCPServer.new(8080)
thread_count = 4
threads = thread_count.times.map do
Thread.new do
clients = []
loop do
readable, _ = IO.select([server] + clients, nil, nil, 0.1)
next unless readable
readable.each do |socket|
if socket == server
clients << server.accept
else
handle_client_event(socket)
end
end
end
end
end
threads.each(&:join)
This hybrid approach balances single-threaded event loop efficiency with multi-core CPU utilization. Each thread handles hundreds or thousands of connections, while multiple threads utilize available CPU cores.
Performance Considerations
TCP performance depends on numerous factors including network conditions, buffer sizes, congestion control algorithms, and application behavior. Understanding these factors enables optimization for specific use cases.
Bandwidth-Delay Product
The bandwidth-delay product (BDP) determines optimal window sizes for maximum throughput. BDP equals bandwidth multiplied by round-trip time:
BDP = bandwidth × RTT
For a 100 Mbps connection with 50ms RTT:
BDP = 100 Mbps × 0.05s = 5 Mb = 625 KB
TCP window sizes should match or exceed BDP for full bandwidth utilization. Default window sizes (64 KB) limit throughput on high-bandwidth, high-latency networks. Window scaling enables windows up to 1 GB.
Nagle's Algorithm Trade-offs
Nagle's algorithm coalesces small writes into larger segments, reducing packet overhead. The algorithm delays transmission when unacknowledged data exists and the current segment is smaller than MSS. This reduces packets but increases latency.
Applications sending many small messages experience delayed transmission. Disabling Nagle's algorithm (TCP_NODELAY) reduces latency but increases packet count. Interactive applications like games and terminals benefit from TCP_NODELAY. Bulk data transfer benefits from Nagle's algorithm.
# Disable Nagle's algorithm for low latency
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_NODELAY, 1)
Socket Buffer Sizing
Send and receive buffers affect throughput and memory usage. Small buffers limit throughput on high-bandwidth connections. Large buffers consume more memory per connection, reducing maximum connection count.
# Increase buffer sizes for high-throughput connections
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 1048576) # 1 MB
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_RCVBUF, 1048576) # 1 MB
Operating systems auto-tune buffer sizes based on connection characteristics. Manual tuning helps when hosting many connections or optimizing specific workloads.
Connection Pooling
Establishing TCP connections involves three-way handshake latency and TLS handshake overhead for secure connections. Connection pooling reuses connections across multiple requests:
class ConnectionPool
def initialize(host, port, size)
@host = host
@port = port
@available = Queue.new
size.times do
@available.push(create_connection)
end
end
def with_connection
conn = @available.pop
yield conn
ensure
@available.push(conn)
end
private
def create_connection
TCPSocket.new(@host, @port)
end
end
pool = ConnectionPool.new('example.com', 80, 10)
pool.with_connection do |socket|
socket.write("GET / HTTP/1.1\r\n\r\n")
response = socket.read
end
Pools reduce connection establishment overhead for workloads with repeated short requests. Web scraping, API clients, and database connections benefit from pooling.
TCP Fast Open
TCP Fast Open (TFO) eliminates one round-trip from connection establishment by sending data in the SYN packet. The client includes a TFO cookie from previous connections, allowing the server to accept data before completing the handshake.
TFO reduces latency by up to one RTT for repeated connections between the same endpoints. Limited operating system and application support restricts TFO adoption.
Keepalive Configuration
TCP keepalive probes detect dead connections by sending periodic packets. Default keepalive intervals (2 hours) delay failure detection. Shorter intervals detect failures faster but increase network traffic:
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE, 1)
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPIDLE, 60) # Start after 60s idle
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPINTVL, 10) # Send every 10s
socket.setsockopt(Socket::SOL_TCP, Socket::TCP_KEEPCNT, 3) # Give up after 3 probes
Application-layer heartbeats provide more control than TCP keepalive but require protocol support.
Congestion Control Algorithm Selection
Different congestion control algorithms optimize for different network conditions. CUBIC (Linux default) optimizes for high-bandwidth networks. BBR focuses on measuring actual bottleneck bandwidth and round-trip time. Reno provides conservative behavior for network stability.
Most applications accept default congestion control. Changing algorithms requires root privileges and affects all connections on the system.
Security Implications
TCP itself provides no security. Data travels unencrypted and unauthenticated over networks. Several attacks target TCP weaknesses.
SYN Flood Attacks
SYN floods exploit the TCP handshake by sending many SYN packets without completing connections. Servers allocate resources for half-open connections, exhausting available connections or memory.
SYN cookies mitigate SYN floods by encoding connection state in sequence numbers. Instead of allocating resources during SYN-ACK, servers store no state and reconstruct connection parameters from the ACK sequence number.
Operating systems enable SYN cookies automatically under load. Applications see no difference in behavior.
Connection Hijacking
TCP connections are vulnerable to hijacking when attackers guess sequence numbers. Injecting packets with correct sequence numbers inserts malicious data into the stream or terminates connections with RST packets.
Initial sequence number randomization makes guessing difficult but not impossible. Off-path attackers observe traffic to estimate sequence numbers. On-path attackers see actual sequence numbers.
TLS protects against hijacking through encryption and authentication. The encrypted payload prevents meaningful injection, and message authentication codes detect tampering.
Denial of Service Through Resource Exhaustion
Attackers establish many connections to exhaust server resources. Even with SYN cookies, completed connections consume memory for buffers, socket structures, and application state.
Rate limiting, connection limits per source IP, and connection timeouts mitigate resource exhaustion. Application-layer authentication reduces impact by rejecting unauthorized connections early.
require 'socket'
class RateLimitedServer
def initialize(port, max_connections_per_ip)
@server = TCPServer.new(port)
@connections = Hash.new(0)
@max_per_ip = max_connections_per_ip
end
def accept_with_limit
loop do
client = @server.accept
ip = client.remote_address.ip_address
if @connections[ip] >= @max_per_ip
client.close
next
end
@connections[ip] += 1
return [client, ip]
end
end
def release(ip)
@connections[ip] -= 1
end
end
Port Scanning and Reconnaissance
TCP three-way handshakes reveal open ports. SYN scanning (sending SYN and analyzing responses) maps services quickly. Servers cannot prevent port scanning but can detect and block scanning sources.
Man-in-the-Middle Attacks
TCP provides no endpoint authentication. Attackers intercepting connections impersonate either endpoint. ARP spoofing, DNS spoofing, and BGP hijacking enable position for man-in-the-middle attacks.
TLS prevents man-in-the-middle attacks through certificate validation. Applications should verify certificates against trusted certificate authorities and check hostname matching.
require 'socket'
require 'openssl'
def secure_connection(host, port)
socket = TCPSocket.new(host, port)
ssl_context = OpenSSL::SSL::SSLContext.new
ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER
ssl_context.cert_store = OpenSSL::X509::Store.new
ssl_context.cert_store.set_default_paths
ssl_socket = OpenSSL::SSL::SSLSocket.new(socket, ssl_context)
ssl_socket.sync_close = true
ssl_socket.hostname = host # Enable SNI and hostname verification
ssl_socket.connect
ssl_socket
end
# Use TLS connection
ssl_socket = secure_connection('example.com', 443)
ssl_socket.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
response = ssl_socket.read
ssl_socket.close
Firewall and Network Segmentation
Limiting TCP connectivity reduces attack surface. Firewalls block unauthorized connections based on source IP, destination port, and other criteria. Network segmentation isolates systems, containing breaches and limiting lateral movement.
Applications should bind to specific interfaces rather than all interfaces when possible:
# Bind only to localhost, preventing external access
server = TCPServer.new('127.0.0.1', 8080)
# Bind to all interfaces
server = TCPServer.new('0.0.0.0', 8080)
Tools & Ecosystem
Ruby's TCP ecosystem includes standard library components, third-party gems, and debugging tools for network programming.
Standard Library Components
The Socket library provides low-level socket access. TCPServer and TCPSocket offer convenient abstractions for common patterns. UDPSocket handles UDP. IPSocket provides IP-specific functionality. BasicSocket defines the base socket interface.
EventMachine
EventMachine implements the Reactor pattern for high-performance network servers:
require 'eventmachine'
module EchoServer
def post_init
puts "Client connected"
end
def receive_data(data)
send_data("Echo: #{data}")
end
def unbind
puts "Client disconnected"
end
end
EventMachine.run do
EventMachine.start_server('0.0.0.0', 8080, EchoServer)
puts "Server running on port 8080"
end
EventMachine handles event loop management, connection lifecycle, and asynchronous operations. The pattern-oriented API simplifies complex server implementations.
Async and Async::IO
The async gem provides fiber-based concurrency for IO operations:
require 'async'
require 'async/io/stream'
require 'async/io/endpoint'
Async do
endpoint = Async::IO::Endpoint.tcp('example.com', 80)
endpoint.connect do |socket|
stream = Async::IO::Stream.new(socket)
stream.write("GET / HTTP/1.1\r\nHost: example.com\r\n\r\n")
response = stream.read_until("\r\n\r\n")
puts response
end
end
Async uses fibers for cooperative multitasking, avoiding threads overhead while maintaining synchronous code structure.
Celluloid::IO
Celluloid::IO combines actor-based concurrency with event-driven IO:
require 'celluloid/io'
class TcpServer
include Celluloid::IO
def initialize(host, port)
@server = Celluloid::IO::TCPServer.new(host, port)
async.run
end
def run
loop do
async.handle_client(@server.accept)
end
end
def handle_client(socket)
data = socket.readpartial(4096)
socket.write("Echo: #{data}")
socket.close
end
end
server = TcpServer.new('0.0.0.0', 8080)
sleep
Celluloid actors run concurrently, each with independent state. Supervisors restart failed actors automatically.
Debugging Tools
tcpdump captures TCP packets for analysis:
tcpdump -i eth0 tcp port 8080 -w capture.pcap
Wireshark provides graphical packet analysis with TCP stream reconstruction, timing analysis, and protocol dissection.
netstat and ss display active connections:
netstat -an | grep :8080
ss -tan sport :8080
strace traces system calls including socket operations:
strace -e trace=network ruby server.rb
lsof lists open sockets per process:
lsof -i TCP:8080
Connection Testing Tools
telnet tests basic TCP connectivity:
telnet example.com 80
GET / HTTP/1.1
Host: example.com
nc (netcat) provides flexible TCP/UDP testing:
nc -zv example.com 80 # Port scan
nc -l 8080 # Listen mode
echo "test" | nc example.com 80 # Send data
Performance Testing
iperf3 measures TCP throughput:
iperf3 -s # Server
iperf3 -c server_ip # Client
ab (Apache Bench) load tests HTTP over TCP:
ab -n 1000 -c 10 http://localhost:8080/
Reference
TCP Header Structure
| Field | Size (bits) | Description |
|---|---|---|
| Source Port | 16 | Sending application port number |
| Destination Port | 16 | Receiving application port number |
| Sequence Number | 32 | Position of first data byte in stream |
| Acknowledgment Number | 32 | Next expected sequence number |
| Data Offset | 4 | TCP header size in 32-bit words |
| Reserved | 3 | Reserved for future use |
| Flags | 9 | Control flags (NS, CWR, ECE, URG, ACK, PSH, RST, SYN, FIN) |
| Window Size | 16 | Receive window size in bytes |
| Checksum | 16 | Error detection checksum |
| Urgent Pointer | 16 | Offset to urgent data |
| Options | Variable | Optional parameters (max 40 bytes) |
TCP Control Flags
| Flag | Name | Purpose |
|---|---|---|
| SYN | Synchronize | Initiates connection and synchronizes sequence numbers |
| ACK | Acknowledge | Acknowledges received data |
| FIN | Finish | Requests connection termination |
| RST | Reset | Aborts connection immediately |
| PSH | Push | Requests immediate data delivery to application |
| URG | Urgent | Indicates urgent data in segment |
| ECE | ECN-Echo | Explicit Congestion Notification echo |
| CWR | Congestion Window Reduced | Congestion window reduced response |
| NS | Nonce Sum | ECN-nonce concealment protection |
TCP States
| State | Description |
|---|---|
| CLOSED | No connection exists |
| LISTEN | Server waiting for connection requests |
| SYN_SENT | Client sent SYN, waiting for SYN-ACK |
| SYN_RECEIVED | Server received SYN, sent SYN-ACK |
| ESTABLISHED | Connection established, data transfer possible |
| FIN_WAIT_1 | Active close initiated, FIN sent |
| FIN_WAIT_2 | Remote FIN acknowledged, waiting for remote FIN |
| CLOSE_WAIT | Remote side closed, waiting for application close |
| CLOSING | Both sides closing simultaneously |
| LAST_ACK | Waiting for final FIN acknowledgment |
| TIME_WAIT | Waiting for delayed segments to expire |
Socket Options
| Option | Level | Description |
|---|---|---|
| SO_KEEPALIVE | SOL_SOCKET | Enable TCP keepalive probes |
| SO_REUSEADDR | SOL_SOCKET | Allow binding to recently used addresses |
| SO_REUSEPORT | SOL_SOCKET | Allow multiple bindings to same port |
| SO_SNDBUF | SOL_SOCKET | Set send buffer size |
| SO_RCVBUF | SOL_SOCKET | Set receive buffer size |
| TCP_NODELAY | SOL_TCP | Disable Nagle's algorithm |
| TCP_KEEPIDLE | SOL_TCP | Keepalive idle time before probes |
| TCP_KEEPINTVL | SOL_TCP | Interval between keepalive probes |
| TCP_KEEPCNT | SOL_TCP | Number of keepalive probes before timeout |
| TCP_CORK | SOL_TCP | Delay sending until full frames available |
Ruby Socket Classes
| Class | Purpose |
|---|---|
| TCPSocket | TCP client connections |
| TCPServer | TCP server listening and accepting |
| UDPSocket | UDP datagram communication |
| UNIXSocket | Unix domain socket client |
| UNIXServer | Unix domain socket server |
| Socket | Low-level socket interface |
| IPSocket | Internet protocol socket base class |
| BasicSocket | Base socket functionality |
Common TCP Ports
| Port | Service | Description |
|---|---|---|
| 20 | FTP-DATA | File Transfer Protocol data |
| 21 | FTP | File Transfer Protocol control |
| 22 | SSH | Secure Shell remote access |
| 23 | Telnet | Unencrypted remote access |
| 25 | SMTP | Simple Mail Transfer Protocol |
| 80 | HTTP | Hypertext Transfer Protocol |
| 110 | POP3 | Post Office Protocol |
| 143 | IMAP | Internet Message Access Protocol |
| 443 | HTTPS | HTTP over TLS/SSL |
| 3306 | MySQL | MySQL database |
| 5432 | PostgreSQL | PostgreSQL database |
| 6379 | Redis | Redis data structure store |
| 27017 | MongoDB | MongoDB database |
Performance Parameters
| Parameter | Typical Value | Impact |
|---|---|---|
| Initial Congestion Window | 10 MSS | Connection startup throughput |
| Maximum Segment Size | 1460 bytes (Ethernet) | Packet size and efficiency |
| Receive Window | 64 KB - 1 GB | Maximum unacknowledged data |
| Retransmission Timeout | 1 sec - 60 sec | Recovery from packet loss |
| TIME_WAIT Duration | 2 MSL (60-240 sec) | Connection reuse delay |
| Default Keepalive Time | 7200 sec (2 hours) | Dead connection detection |
Congestion Control Algorithms
| Algorithm | Characteristics | Use Case |
|---|---|---|
| Reno | Conservative, multiplicative decrease | General purpose, stable networks |
| CUBIC | High-bandwidth optimized, less aggressive | Default on Linux, fast networks |
| BBR | Bandwidth and RTT probing | Variable networks, minimizing bufferbloat |
| Vegas | Delay-based congestion detection | Low-latency requirements |
| Westwood+ | Bandwidth estimation | Wireless networks |
Ruby Socket Error Classes
| Error | Trigger Condition |
|---|---|
| Errno::ECONNREFUSED | Remote host actively refused connection |
| Errno::ETIMEDOUT | Connection attempt timed out |
| Errno::ENETUNREACH | Network unreachable |
| Errno::EHOSTUNREACH | Host unreachable |
| Errno::EADDRINUSE | Address already in use |
| Errno::EADDRNOTAVAIL | Address not available |
| IO::WaitReadable | Non-blocking read would block |
| IO::WaitWritable | Non-blocking write would block |
| EOFError | Connection closed by remote peer |
| SocketError | Generic socket error |