Skip to content

Network Fundamentals Every Software Developer Should Know

A practical glossary of essential networking concepts for developers - from protocols and DNS to debugging tools and security basics.

Abstract

Understanding networking fundamentals isn't just for network engineers - it's essential knowledge for any software developer. Whether you're debugging a production issue during an incident, optimizing API performance, or architecting a distributed system, network concepts come up constantly. This guide provides a practical glossary of networking essentials with real-world context, common gotchas, and debugging scenarios that I've encountered while building backend systems and troubleshooting production issues.

Why Developers Need Network Knowledge

Here's what I've learned: you can write perfect application code, but if you don't understand how data moves between your client and server, you'll struggle with:

  • Debugging mysterious timeouts - Is it DNS? TCP handshake? SSL negotiation? Application logic?
  • Performance optimization - Why does your API feel slow? Is it latency, bandwidth, or connection overhead?
  • Security decisions - Understanding TLS, certificates, and network security helps you make informed choices
  • Infrastructure design - Load balancing, CDN configuration, and service communication patterns
  • Production incidents - Network issues often manifest as application problems

Working with distributed systems taught me that network problems are application problems. You can't separate the two.

Network Layers & Models

OSI Model

The OSI (Open Systems Interconnection) model divides networking into seven layers. While you don't need to memorize all layers, understanding the concept helps troubleshooting:

Layer 7: Application  (HTTP, FTP, SMTP)Layer 6: Presentation (SSL/TLS, encryption)Layer 5: Session  (connection management)Layer 4: Transport  (TCP, UDP)Layer 3: Network  (IP, routing)Layer 2: Data Link  (Ethernet, MAC addresses)Layer 1: Physical  (cables, signals)

Why it matters: When debugging, knowing which layer a problem occurs at saves time. DNS issues are Layer 7, routing problems are Layer 3, and physical connectivity is Layer 1.

TCP/IP Model

The practical model we actually use collapses OSI into four layers:

Application Layer  (HTTP, DNS, SSH)Transport Layer  (TCP, UDP)Internet Layer  (IP, ICMP)Link Layer  (Ethernet, Wi-Fi)

Real-world context: Most developer troubleshooting happens at the Application and Transport layers. Understanding IP helps with routing issues, and Link layer problems usually require network admin intervention.

Core Protocols

HTTP/HTTPS

HTTP (Hypertext Transfer Protocol) is the foundation of web communication. It's a request-response protocol where clients send requests and servers return responses.

Key characteristics:

  • Stateless (each request is independent)
  • Text-based protocol
  • Methods: GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD
  • Status codes: 2xx (success), 3xx (redirect), 4xx (client error), 5xx (server error)

HTTPS adds SSL/TLS encryption on top of HTTP. The 'S' means your data is encrypted in transit.

Common gotcha: HTTPS isn't just encryption - it also provides authentication (proving you're talking to the right server) and integrity (data wasn't modified in transit).

Practical example - Making an HTTP request:

bash
# Simple GET requestcurl -v https://api.example.com/users
# POST with JSON bodycurl -X POST https://api.example.com/users \  -H "Content-Type: application/json" \  -d '{"name": "John", "email": "[email protected]"}'
# See response headerscurl -I https://api.example.com/health

When to use: APIs, web applications, RESTful services. HTTPS should be default for anything over the internet.

HTTP/2 and HTTP/3

HTTP/2 improves on HTTP/1.1 with:

  • Multiplexing (multiple requests over single connection)
  • Header compression
  • Server push
  • Binary protocol (not text-based)

HTTP/3 uses QUIC instead of TCP:

  • Faster connection establishment
  • Better handling of packet loss
  • Built on UDP with reliability added

Real-world impact: HTTP/2 significantly reduces latency for websites with many resources. HTTP/3 shines on mobile networks with packet loss.

Common gotcha: HTTP/2 requires HTTPS. You can't use it over plain HTTP in browsers.

TCP vs UDP

TCP (Transmission Control Protocol):

  • Connection-oriented (handshake before data transfer)
  • Reliable (guarantees delivery and order)
  • Flow control and congestion control
  • Slower but dependable

UDP (User Datagram Protocol):

  • Connectionless (fire and forget)
  • Unreliable (no delivery guarantee)
  • No ordering guarantee
  • Fast but risky

When to use TCP:

  • HTTP/HTTPS traffic
  • Database connections
  • File transfers
  • Any time you need reliability

When to use UDP:

  • Video streaming (occasional lost frame is OK)
  • Gaming (speed over perfect accuracy)
  • DNS queries (can retry if lost)
  • Real-time metrics (losing one data point is acceptable)

Practical example - TCP handshake visualization:

Common debugging scenario: Seeing TCP retransmissions? Check network congestion, packet loss, or firewall issues.

WebSocket

WebSocket provides full-duplex communication over a single TCP connection. Unlike HTTP's request-response, WebSocket allows bi-directional streaming.

Key characteristics:

  • Starts as HTTP upgrade request
  • Persistent connection
  • Low overhead for message framing
  • Real-time, two-way communication

When to use:

  • Chat applications
  • Live notifications
  • Real-time dashboards
  • Collaborative editing
  • Gaming

Practical example - WebSocket in Node.js:

typescript
import WebSocket from 'ws';
// Serverconst wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', (ws) => {  console.log('Client connected');
  ws.on('message', (message) => {    console.log('Received:', message);    // Broadcast to all clients    wss.clients.forEach((client) => {      if (client.readyState === WebSocket.OPEN) {        client.send(message);      }    });  });
  ws.on('close', () => {    console.log('Client disconnected');  });});
// Clientconst ws = new WebSocket('ws://localhost:8080');
ws.on('open', () => {  ws.send('Hello Server!');});
ws.on('message', (data) => {  console.log('Received:', data);});

Common gotcha: WebSocket connections can be closed by proxies or load balancers with idle timeouts. Implement heartbeat/ping-pong to keep connections alive.

gRPC

gRPC is a modern RPC framework using HTTP/2 and Protocol Buffers. It's particularly popular for microservices communication.

Key characteristics:

  • Binary protocol (efficient)
  • Strongly typed (Protocol Buffers)
  • Supports streaming (client, server, bi-directional)
  • Code generation from .proto files
  • Built-in load balancing and retries

When to use:

  • Microservices communication
  • High-performance APIs
  • Polyglot environments (many language support)
  • Streaming data

Practical example - Simple gRPC definition:

protobuf
syntax = "proto3";
service UserService {  rpc GetUser (GetUserRequest) returns (User);  rpc ListUsers (ListUsersRequest) returns (stream User);}
message GetUserRequest {  string user_id = 1;}
message User {  string id = 1;  string name = 2;  string email = 3;}

When not to use: Browser clients (limited support), public-facing APIs (REST is more universal), teams unfamiliar with Protocol Buffers.

DNS & Name Resolution

How DNS Works

DNS (Domain Name System) translates human-readable domain names to IP addresses. It's a distributed, hierarchical system.

DNS query flow:

DNS record types:

  • A: Maps domain to IPv4 address
  • AAAA: Maps domain to IPv6 address
  • CNAME: Alias to another domain
  • MX: Mail server records
  • TXT: Text records (often used for verification, SPF, DKIM)
  • NS: Nameserver records
  • SOA: Start of Authority (zone information)

Practical debugging - DNS lookup tools:

bash
# Basic DNS lookupdig example.com
# Query specific record typedig example.com AAAA
# Use specific DNS serverdig @8.8.8.8 example.com
# Trace DNS resolution pathdig +trace example.com
# Reverse DNS lookup (IP to domain)dig -x 192.0.2.1
# Short answer onlydig +short example.com

Common issues I've debugged:

  • DNS caching: Changed DNS but old IP still resolving? Check TTL (Time To Live)
  • DNS propagation: Changes can take 24-48 hours to propagate globally
  • Local cache: Application might cache DNS results (check your DNS client settings)
  • Split-horizon DNS: Internal vs external DNS returning different results

Real-world gotcha: DNS failures are often silent. Your application might use a stale cached value while DNS is broken, masking the problem until cache expires.

DNS TTL

TTL (Time To Live) tells resolvers how long to cache a DNS record. Measured in seconds.

Strategy:

  • Long TTL (hours/days): Stable infrastructure, reduce DNS load
  • Short TTL (minutes): Before planned changes for faster cutover
  • Balance: 300-3600 seconds (5 minutes to 1 hour) works for most cases

Pre-migration pattern:

bash
# 1 week before migration: Lower TTL to 300 seconds# Migration day: Change DNS records# 1 week after migration: Raise TTL back to 3600+ seconds

IP Addressing & Routing

IPv4 Addressing

IPv4 address: 32-bit number written as four octets (0-255) separated by dots.

Example: 192.168.1.100

Special ranges:

  • Private addresses (not routable on internet):
    • 10.0.0.0/8 (10.0.0.0 - 10.255.255.255)
    • 172.16.0.0/12 (172.16.0.0 - 172.31.255.255)
    • 192.168.0.0/16 (192.168.0.0 - 192.168.255.255)
  • Loopback: 127.0.0.0/8 (localhost)
  • Link-local: 169.254.0.0/16 (auto-configuration when DHCP fails)

CIDR notation: 192.168.1.0/24 means first 24 bits are network, last 8 bits are host.

  • /24 = 256 addresses (254 usable, 2 reserved)
  • /16 = 65,536 addresses
  • /8 = 16,777,216 addresses

Practical example - Checking your IP:

bash
# Public IPcurl ifconfig.me
# Local IP (Linux/Mac)ifconfig | grep "inet " | grep -v 127.0.0.1
# Local IP (Linux)ip addr show

IPv6 Addressing

IPv6 address: 128-bit number written as eight groups of four hexadecimal digits.

Example: 2001:0db8:85a3:0000:0000:8a2e:0370:7334

Shortened: 2001:db8:85a3::8a2e:370:7334 (consecutive zeros can be replaced with ::)

Why IPv6 matters: IPv4 addresses are exhausted. Cloud providers increasingly use IPv6, and modern applications should support both.

Common gotcha: Many tools default to IPv4. Explicitly test IPv6 connectivity.

NAT (Network Address Translation)

NAT allows multiple devices on a private network to share a single public IP address. Your home router does this.

Why developers care:

  • Understanding private vs public IPs
  • Debugging connection issues (NAT traversal)
  • Security implications (NAT provides basic firewalling)
  • Cloud environments (VPC networking, NAT gateways)

AWS example: Private subnet instances use NAT Gateway to access internet while remaining unreachable from internet.

Ports & Common Services

Port Numbers

Ports identify specific services on a host. Range: 0-65535

Port ranges:

  • Well-known ports (0-1023): Reserved for common services, require root/admin
  • Registered ports (1024-49151): Used by applications
  • Dynamic/Private ports (49152-65535): Temporary ports for client connections

Common ports you should know:

PortProtocolService
20/21FTPFile Transfer (data/control)
22SSHSecure Shell
25SMTPEmail sending
53DNSDomain Name System
80HTTPWeb traffic
443HTTPSSecure web traffic
465/587SMTPSecure email (SSL/TLS)
3000-Common dev server (Node.js)
3306MySQLDatabase
5432PostgreSQLDatabase
6379RedisCache/database
8080HTTPAlternative HTTP (dev/proxy)
8443HTTPSAlternative HTTPS
27017MongoDBDatabase

Practical debugging - Check port usage:

bash
# Check if port is listening (Linux)netstat -tuln | grep :443
# See what's using a portlsof -i :3000
# Test if port is opennc -zv example.com 443
# Test connection with timeouttimeout 5 bash -c 'cat < /dev/null > /dev/tcp/example.com/443' && echo "Open" || echo "Closed"

Common issue: Port already in use. Find and kill the process:

bash
# Find process using port 3000lsof -ti:3000
# Kill process using port 3000kill $(lsof -ti:3000)
# Forcefully kill if neededkill -9 $(lsof -ti:3000)

Firewalls & Port Security

Firewalls control which ports are accessible. Security groups in AWS/Azure are essentially firewalls.

Best practices:

  • Only open necessary ports
  • Use specific source IPs when possible (not 0.0.0.0/0)
  • Different rules for internal vs external traffic
  • Document why each port is open

Real-world scenario: API suddenly unreachable. Check firewall rules before diving into application code. I've spent hours debugging "broken" code when it was just a security group rule blocking traffic.

Load Balancing & Distribution

Load Balancer Types

Load balancers distribute traffic across multiple servers for reliability and scalability.

Layer 4 (Transport Layer) Load Balancing:

  • Routes based on IP address and port
  • Fast (no application layer inspection)
  • Protocol-agnostic (works with any TCP/UDP traffic)
  • Examples: AWS Network Load Balancer, HAProxy in TCP mode

Layer 7 (Application Layer) Load Balancing:

  • Routes based on HTTP headers, URL path, cookies
  • Content-based routing
  • SSL termination
  • Examples: AWS Application Load Balancer, NGINX, HAProxy in HTTP mode

When to use Layer 4:

  • High throughput requirements
  • Non-HTTP protocols
  • Simple round-robin distribution
  • WebSocket with sticky sessions handled elsewhere

When to use Layer 7:

  • Path-based routing (/api/* to one service, /admin/* to another)
  • Host-based routing (multiple domains on one load balancer)
  • SSL offloading
  • Request modification/headers

Load Balancing Algorithms

Round Robin: Distribute requests equally in sequence. Simple but doesn't account for server load.

Least Connections: Send to server with fewest active connections. Good for long-lived connections.

IP Hash: Route based on client IP. Same client always goes to same server (session affinity without sticky sessions).

Weighted: Assign weights to servers (for different capacity). Useful during migrations or canary deployments.

Real-world pattern - Blue/Green deployment:

Load Balancer Config:- Blue environment: weight 100- Green environment: weight 0
Deploy to Green, test, then:- Blue: 90, Green: 10 (canary)- Blue: 50, Green: 50 (gradual shift)- Blue: 0, Green: 100 (complete cutover)

Health Checks

Health checks verify server availability. Load balancer removes unhealthy servers from rotation.

Health check strategies:

  • TCP check: Can connect to port? (minimal check)
  • HTTP check: Returns 200 OK? (application-aware)
  • Deep health check: Query database, check dependencies

Implementation example:

typescript
// Simple health check endpointapp.get('/health', (req, res) => {  res.status(200).json({ status: 'ok' });});
// Deep health checkapp.get('/health/deep', async (req, res) => {  try {    // Check database    await db.query('SELECT 1');
    // Check Redis    await redis.ping();
    // Check critical dependencies    const apiReachable = await checkExternalAPI();
    if (apiReachable) {      res.status(200).json({        status: 'healthy',        dependencies: {          database: 'ok',          cache: 'ok',          externalAPI: 'ok'        }      });    } else {      throw new Error('External API unreachable');    }  } catch (error) {    res.status(503).json({      status: 'unhealthy',      error: error.message    });  }});

Common gotcha: Health check failures cause cascading issues. If check is too aggressive, healthy servers get marked unhealthy. If too lenient, unhealthy servers stay in rotation.

Content Delivery Networks (CDN)

CDN Basics

CDN distributes content across geographically distributed edge servers. Clients connect to nearest edge location for faster delivery.

Key concepts:

  • Origin: Your original server
  • Edge location: CDN's distributed servers
  • Cache: Content stored at edge locations
  • TTL: How long content stays cached
  • Cache invalidation: Removing stale content

What to cache:

  • Static assets (images, CSS, JavaScript)
  • Infrequently changing content
  • Publicly accessible resources

What not to cache:

  • Dynamic, user-specific content
  • Authenticated API responses
  • Real-time data

Cache Control Headers

Control caching behavior with HTTP headers:

typescript
// Cache for 1 year (immutable assets with fingerprints)res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
// Cache for 1 hourres.setHeader('Cache-Control', 'public, max-age=3600');
// Don't cacheres.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate');
// Cache but revalidateres.setHeader('Cache-Control', 'public, max-age=0, must-revalidate');

Cache-Control directives:

  • public: Can be cached by any cache
  • private: Only client browser can cache (not CDN)
  • no-cache: Revalidate with origin before using cached version
  • no-store: Don't cache at all
  • max-age: Cache lifetime in seconds
  • immutable: Content will never change (aggressive caching)

Real-world pattern - Asset fingerprinting:

app-abc123.js  # Hash in filename, cache foreverapp.js  # No hash, short cache or no-cache

CDN Gotchas

Problem: Deployed new version but users see old cached content.

Solutions:

  • Use versioned filenames (app.v2.js or app.abc123.js)
  • Invalidate CDN cache (can cost money, takes time)
  • Lower TTL before deployment

Problem: CDN caching authenticated content.

Solution: Use Cache-Control: private for user-specific content, or include Vary: Authorization header.

SSL/TLS & Certificates

How SSL/TLS Works

SSL/TLS provides encryption, authentication, and integrity for network communication.

TLS handshake process (simplified):

  1. Client sends supported cipher suites and TLS version
  2. Server responds with chosen cipher and its certificate
  3. Client verifies certificate (signed by trusted CA)
  4. Client and server exchange keys and establish encrypted connection
  5. Application data flows over encrypted channel

Certificate components:

  • Public key: Used to encrypt data sent to server
  • Private key: Used by server to decrypt data (kept secret)
  • Certificate Authority (CA): Trusted entity that signs certificates
  • Certificate chain: Your cert → Intermediate CA → Root CA

Certificate Types

Domain Validation (DV): Proves you control the domain. Automated, fast, free (Let's Encrypt).

Organization Validation (OV): Includes organization verification. More trust, more expensive.

Extended Validation (EV): Highest level of validation. Shows organization name in browser. Most expensive.

Wildcard: Covers all subdomains (*.example.com). Convenient but higher security risk if compromised.

Multi-domain (SAN): Covers multiple specific domains in one certificate.

Practical Certificate Management

Let's Encrypt example - Free automated certificates:

bash
# Install certbotsudo apt-get install certbot
# Get certificate (automated)sudo certbot certonly --standalone -d example.com -d www.example.com
# Auto-renewal (add to cron)0 0 * * * certbot renew --quiet

Common certificate issues:

Expired certificate:

bash
# Check certificate expirationecho | openssl s_client -connect example.com:443 2>/dev/null | \  openssl x509 -noout -dates

Certificate chain issues:

bash
# Verify certificate chainopenssl s_client -connect example.com:443 -showcerts
# Test with specific CA bundlecurl --cacert /path/to/ca-bundle.crt https://example.com

Wrong domain on certificate:

bash
# Check certificate subjectecho | openssl s_client -connect example.com:443 2>/dev/null | \  openssl x509 -noout -subject -ext subjectAltName

Self-signed certificates: Fine for development, never for production. Browsers will show warnings.

TLS Best Practices

  • Use TLS 1.2 or 1.3 (TLS 1.0/1.1 are deprecated)
  • Strong cipher suites (avoid weak ciphers like RC4, DES)
  • Certificate pinning for mobile apps (optional, adds security)
  • Automated renewal (certificates expire, usually 90 days for Let's Encrypt)
  • HSTS header tells browsers to only use HTTPS
typescript
// Enable HSTSres.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');

Network Security Basics

Firewalls

Firewall filters network traffic based on rules. Can operate at different layers.

Types:

  • Packet filtering: Layer 3/4 (IP, port, protocol)
  • Stateful inspection: Tracks connection state
  • Application firewall: Layer 7 (inspects HTTP, etc.)
  • WAF (Web Application Firewall): Protects against web attacks (SQL injection, XSS)

Cloud firewall equivalents:

  • AWS: Security Groups, Network ACLs, AWS WAF
  • Azure: Network Security Groups, Application Gateway WAF
  • GCP: VPC Firewall Rules, Cloud Armor

Best practice: Defense in depth. Multiple layers of security.

VPN (Virtual Private Network)

VPN creates encrypted tunnel over public network, making it appear you're on a private network.

Use cases:

  • Secure remote access to corporate network
  • Accessing geographically restricted services
  • Encrypting traffic on untrusted networks (coffee shop Wi-Fi)

Types:

  • Site-to-Site VPN: Connect two networks (e.g., office to AWS VPC)
  • Remote Access VPN: Individual users connect to network
  • SSL VPN: Browser-based, no client needed
  • IPsec VPN: Traditional, requires client software

Developer perspective: If you're accessing production systems remotely, you're likely using VPN. Understand connection requirements and troubleshooting.

Common Attack Vectors

DDoS (Distributed Denial of Service): Overwhelming server with traffic. Mitigation: CDN, rate limiting, auto-scaling.

Man-in-the-Middle: Intercepting communication. Mitigation: TLS/SSL, certificate validation.

DNS Hijacking: Redirecting DNS to malicious servers. Mitigation: DNSSEC, trusted DNS providers.

Port Scanning: Discovering open ports. Mitigation: Close unnecessary ports, use firewall.

SQL Injection: Malicious SQL in inputs. Mitigation: Parameterized queries, input validation.

XSS (Cross-Site Scripting): Injecting malicious scripts. Mitigation: Output encoding, CSP headers.

Essential Networking Tools

ping

Purpose: Test connectivity and measure latency.

bash
# Basic pingping example.com
# Limit to 5 packetsping -c 5 example.com
# Flood ping (testing, requires root)sudo ping -f example.com

What it tells you:

  • Can you reach the host?
  • What's the latency?
  • Is there packet loss?

Common output:

64 bytes from example.com (93.184.216.34): icmp_seq=1 ttl=56 time=15.2 ms
  • time=15.2 ms: Round-trip latency
  • ttl=56: Time to live (hops remaining)

Gotcha: Some servers block ICMP (ping). No response doesn't always mean server is down.

traceroute / tracepath

Purpose: Show path packets take to destination.

bash
# Trace route to destinationtraceroute example.com
# Alternative (doesn't require root)tracepath example.com
# Trace with ICMP instead of UDPtraceroute -I example.com

What it tells you:

  • Network path to destination
  • Where latency is introduced
  • Where packets are being dropped

Interpreting results:

 1  192.168.1.1 (192.168.1.1)  1.234 ms 2  10.0.0.1 (10.0.0.1)  5.678 ms 3  * * * 4  example.com (93.184.216.34)  15.2 ms
  • Each line is a hop (router)
  • * * * means hop didn't respond (often firewalled)
  • Large jump in latency shows bottleneck

curl

Purpose: Transfer data using various protocols. Essential for API testing.

bash
# GET requestcurl https://api.example.com/users
# POST with JSONcurl -X POST https://api.example.com/users \  -H "Content-Type: application/json" \  -d '{"name": "John"}'
# Follow redirectscurl -L https://example.com
# Show response headerscurl -i https://example.com
# Show request/response headerscurl -v https://example.com
# Save response to filecurl -o output.html https://example.com
# Download with progress barcurl -# -O https://example.com/file.zip
# Test with specific IP (bypass DNS)curl --resolve example.com:443:93.184.216.34 https://example.com
# Custom headerscurl -H "Authorization: Bearer token123" https://api.example.com
# Measure time breakdowncurl -w "@curl-format.txt" -o /dev/null -s https://example.com

curl timing format file (curl-format.txt):

time_namelookup:  %{time_namelookup}s\ntime_connect:  %{time_connect}s\ntime_appconnect:  %{time_appconnect}s\ntime_pretransfer: %{time_pretransfer}s\ntime_redirect:  %{time_redirect}s\ntime_starttransfer: %{time_starttransfer}s\ntime_total:  %{time_total}s\n

netstat / ss

Purpose: Network statistics - active connections, listening ports, routing tables.

bash
# Show all listening TCP portsnetstat -tuln
# Show all connections with process infosudo netstat -tulnp
# Show routing tablenetstat -r
# Modern alternative (faster)ss -tuln
# Show specific portss -tuln | grep :443
# Show connections by statess -t state established

States you'll see:

  • LISTEN: Waiting for connections
  • ESTABLISHED: Active connection
  • TIME_WAIT: Connection closed, waiting to ensure closure
  • CLOSE_WAIT: Remote end closed, local end hasn't yet

Debugging scenario: Too many TIME_WAIT connections? Might need to adjust TCP settings or connection pooling.

nslookup / dig

Purpose: DNS queries and troubleshooting.

bash
# Basic lookupnslookup example.com
# Query specific DNS servernslookup example.com 8.8.8.8
# Dig (more detailed)dig example.com
# Query specific record typedig example.com AAAA
# Short answerdig +short example.com
# Trace DNS resolutiondig +trace example.com
# Reverse lookupdig -x 93.184.216.34

tcpdump / wireshark

Purpose: Packet capture and analysis. The ultimate debugging tool for network issues.

bash
# Capture on interface (requires root)sudo tcpdump -i eth0
# Capture specific portsudo tcpdump -i eth0 port 443
# Capture and save to filesudo tcpdump -i eth0 -w capture.pcap
# Read from filetcpdump -r capture.pcap
# Capture specific hostsudo tcpdump -i eth0 host example.com
# HTTP traffic onlysudo tcpdump -i eth0 -A port 80

When to use: Last resort when nothing else helps. You'll see every packet, which is overwhelming but sometimes necessary.

Wireshark: GUI version of tcpdump with powerful filtering and analysis. Use for deep inspection of saved packet captures.

nc (netcat)

Purpose: Swiss army knife for TCP/UDP connections.

bash
# Test if port is opennc -zv example.com 443
# Listen on port (simple server)nc -l 8080
# Connect and send dataecho "Hello" | nc example.com 80
# Chat between two machines# Machine 1: nc -l 8080# Machine 2: nc machine1-ip 8080
# Simple HTTP requestprintf "GET / HTTP/1.1\r\nHost: example.com\r\n\r\n" | nc example.com 80

telnet

Purpose: Test TCP connections (unencrypted). Useful for debugging protocols.

bash
# Test SMTPtelnet mail.example.com 25
# Test HTTPtelnet example.com 80# Then type: GET / HTTP/1.1 [Enter]#  Host: example.com [Enter]#  [Enter]
# Test if port is opentelnet example.com 443

Note: Most systems don't include telnet by default anymore. Use nc instead.

Practical Debugging Scenarios

Scenario 1: API Timeout

Problem: API calls timing out randomly.

Debugging approach:

bash
# 1. Check if server is reachableping api.example.com
# 2. Check DNS resolution timetime dig api.example.com
# 3. Test connectioncurl -w "@curl-format.txt" -o /dev/null https://api.example.com
# 4. Check from different location# Is it network path issue or server issue?
# 5. Monitor active connectionswatch -n 1 'ss -s'
# 6. Check for packet lossping -c 100 api.example.com | tail -n 3

What I've learned: Timeouts are often network-related, not application bugs. Check network health before diving into code.

Scenario 2: SSL Certificate Error

Problem: HTTPS connection failing with certificate error.

Debugging approach:

bash
# 1. Check certificate detailsecho | openssl s_client -connect example.com:443 -servername example.com
# 2. Check expirationecho | openssl s_client -connect example.com:443 2>/dev/null | \  openssl x509 -noout -dates
# 3. Verify certificate chaincurl -v https://example.com
# 4. Check certificate matches domainecho | openssl s_client -connect example.com:443 2>/dev/null | \  openssl x509 -noout -text | grep DNS:
# 5. Test with custom CA bundle (if using private CA)curl --cacert /path/to/ca.crt https://example.com

Scenario 3: DNS Resolution Issues

Problem: Domain resolving to wrong IP or not resolving at all.

Debugging approach:

bash
# 1. Check what your system resolves todig example.com
# 2. Check with different DNS serversdig @8.8.8.8 example.com  # Google DNSdig @1.1.1.1 example.com  # Cloudflare DNSdig @8.8.4.4 example.com  # Google DNS backup
# 3. Clear local DNS cache (Mac)sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
# 4. Clear local DNS cache (Linux)sudo systemd-resolve --flush-caches
# 5. Check if it's DNS propagation issue# Use online tools: whatsmydns.net
# 6. Verify DNS records at authoritative serverdig +trace example.com

Real-world tip: DNS issues often appear as intermittent failures because of caching at multiple levels (application, OS, resolver, TTL).

Scenario 4: Port Already in Use

Problem: Can't start server - port already in use.

Debugging approach:

bash
# 1. Find what's using the portlsof -i :3000
# 2. Kill the processkill $(lsof -ti:3000)
# 3. If kill doesn't workkill -9 $(lsof -ti:3000)
# 4. Check if port is actually free nownetstat -tuln | grep :3000
# 5. Alternative - use different port or configure port reuse# In Node.js:# server.listen(3000, { reuseAddr: true })

Scenario 5: High Latency

Problem: Application feels slow, debugging where latency comes from.

Measuring with curl:

bash
# Create curl timing formatcat > curl-format.txt << 'EOF'\n    time_namelookup:  %{time_namelookup}s\n       time_connect:  %{time_connect}s\n    time_appconnect:  %{time_appconnect}s\n   time_pretransfer:  %{time_pretransfer}s\n      time_redirect:  %{time_redirect}s\n time_starttransfer:  %{time_starttransfer}s\n                    ----------\n         time_total:  %{time_total}s\n\nEOF
# Measure request timingcurl -w "@curl-format.txt" -o /dev/null -s https://api.example.com

Interpreting results:

  • High time_namelookup: DNS slow
  • High time_connect: Network latency or server not responding
  • High time_appconnect: SSL handshake slow
  • High time_starttransfer: Server processing slow
  • High time_total with low other times: Large response body

Key Takeaways

Working with networks taught me several lessons:

1. Network problems look like application problems. Before diving into code, rule out network issues. Check connectivity, DNS, certificates, and firewall rules.

2. Layer your debugging. Start at high level (can I reach the host?) and work down (TCP handshake, SSL negotiation, HTTP response).

3. Master basic tools. curl, dig, netstat/ss, and tcpdump will solve 90% of network debugging. Learn them well.

4. DNS is always the culprit. When something's broken, check DNS first. DNS caching, propagation, and TTL cause subtle issues.

5. Measure, don't guess. Use timing tools to identify where latency comes from. Application code? Network? SSL? Database?

6. Security is part of networking. SSL/TLS, firewalls, and VPNs aren't optional add-ons. Build them into your architecture from the start.

7. Documentation matters. Document your network architecture, firewall rules, and port usage. Future you (or your team) will thank you during incidents.

8. Test across the stack. Test locally, in staging, and from different geographic locations. Network behavior varies by environment.

Understanding these fundamentals won't make you a network engineer, but it will make you a better developer. You'll debug issues faster, make informed architectural decisions, and build more reliable systems. The network is just another layer of the stack - treat it as seriously as your application code.

References

Related Posts