TCP vs UDP
TCP provides reliability and ordering at cost of latency. UDP provides speed at cost of reliability. Choose based on requirements.
Understanding networking fundamentals is crucial for designing distributed systems. The transport layer protocols you choose directly impact:
TCP is connection-oriented and provides reliable, ordered delivery of data.
Characteristics:
Use Cases:
Trade-offs:
UDP is connectionless and provides unreliable, unordered delivery.
Characteristics:
Use Cases:
Trade-offs:
DNS translates human-readable domain names (like example.com) to IP addresses (like 192.0.2.1).
DNS Resolution Steps:
Performance Impact:
Best Practices:
HTTP/2 is a binary protocol that improves upon HTTP/1.1 with multiplexing, header compression, and server push.
Multiplexing:
Header Compression:
Server Push:
Binary Protocol:
Impact on Application Design:
QUIC (Quick UDP Internet Connections) is a UDP-based transport protocol developed by Google. It provides TCP-like reliability with lower latency.
Built-in Encryption:
Connection Migration:
Multiplexing:
Faster Connection Establishment:
Use Cases:
Problem: Creating new TCP connections is expensive (3-way handshake).
Solution: Reuse connections via connection pooling.
import httpxfrom typing import Optional
class ConnectionPool: """HTTP connection pool"""
def __init__(self, base_url: str, max_connections: int = 10): self.client = httpx.Client( base_url=base_url, limits=httpx.Limits( max_connections=max_connections, max_keepalive_connections=5 ), timeout=httpx.Timeout(10.0) )
def get(self, path: str) -> dict: """GET request using pooled connection""" response = self.client.get(path) response.raise_for_status() return response.json()
def close(self): """Close connection pool""" self.client.close()
# Usagepool = ConnectionPool("https://api.example.com")
# Reuses connectionsdata1 = pool.get("/users/1")data2 = pool.get("/users/2")data3 = pool.get("/orders/123")
pool.close()import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.net.URI;import java.time.Duration;
public class ConnectionPool { private final HttpClient client; private final String baseUrl;
public ConnectionPool(String baseUrl) { this.baseUrl = baseUrl; this.client = HttpClient.newBuilder() .connectTimeout(Duration.ofSeconds(10)) .build(); }
public String get(String path) throws Exception { // GET request using pooled connection HttpRequest request = HttpRequest.newBuilder() .uri(URI.create(baseUrl + path)) .timeout(Duration.ofSeconds(10)) .build();
HttpResponse<String> response = client.send( request, HttpResponse.BodyHandlers.ofString() );
return response.body(); }}
// UsageConnectionPool pool = new ConnectionPool("https://api.example.com");
// Reuses connectionsString data1 = pool.get("/users/1");String data2 = pool.get("/users/2");String data3 = pool.get("/orders/123");import axios, { AxiosInstance } from 'axios';
class ConnectionPool { // HTTP connection pool private client: AxiosInstance;
constructor(baseUrl: string) { this.client = axios.create({ baseURL: baseUrl, timeout: 10000, // Reuse connections httpAgent: new (require('http').Agent)({ keepAlive: true, maxSockets: 10 }), httpsAgent: new (require('https').Agent)({ keepAlive: true, maxSockets: 10 }) }); }
async get(path: string): Promise<any> { // GET request using pooled connection const response = await this.client.get(path); return response.data; }}
// Usageconst pool = new ConnectionPool("https://api.example.com");
// Reuses connectionsconst data1 = await pool.get("/users/1");const data2 = await pool.get("/users/2");const data3 = await pool.get("/orders/123");#include <curl/curl.h>#include <string>#include <memory>
class ConnectionPool {private: CURL* curl; std::string baseUrl;
public: ConnectionPool(const std::string& baseUrl) : baseUrl(baseUrl) { curl = curl_easy_init(); // Enable connection reuse curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L); curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, 120L); }
std::string get(const std::string& path) { std::string url = baseUrl + path; std::string response;
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);
curl_easy_perform(curl); return response; }
~ConnectionPool() { curl_easy_cleanup(curl); }
private: static size_t writeCallback(void* contents, size_t size, size_t nmemb, void* userp) { ((std::string*)userp)->append((char*)contents, size * nmemb); return size * nmemb; }};
// UsageConnectionPool pool("https://api.example.com");
// Reuses connectionsstd::string data1 = pool.get("/users/1");std::string data2 = pool.get("/users/2");std::string data3 = pool.get("/orders/123");using System;using System.Net.Http;using System.Threading.Tasks;
public class ConnectionPool { // HTTP connection pool private readonly HttpClient client; private readonly string baseUrl;
public ConnectionPool(string baseUrl) { this.baseUrl = baseUrl; this.client = new HttpClient { BaseAddress = new Uri(baseUrl), Timeout = TimeSpan.FromSeconds(10) }; // Connection reuse handled by HttpClient }
public async Task<string> GetAsync(string path) { // GET request using pooled connection var response = await client.GetAsync(path); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); }
public void Dispose() { client?.Dispose(); }}
// Usageusing var pool = new ConnectionPool("https://api.example.com");
// Reuses connectionsvar data1 = await pool.GetAsync("/users/1");var data2 = await pool.GetAsync("/users/2");var data3 = await pool.GetAsync("/orders/123");For high-throughput applications, use async I/O to handle many connections efficiently.
Benefits:
Use Cases:
Choose TCP when:
Choose UDP when:
Choose HTTP/2 when:
Choose QUIC/HTTP/3 when:
TCP vs UDP
TCP provides reliability and ordering at cost of latency. UDP provides speed at cost of reliability. Choose based on requirements.
DNS Impact
DNS resolution adds latency (20-120ms first lookup). Cache DNS responses. DNS failures cause complete outages.
HTTP/2 Benefits
Multiplexing, header compression, server push reduce latency. Single connection handles multiple requests efficiently.
QUIC Advantages
Faster connection establishment, built-in encryption, connection migration. Better for mobile and high-latency networks.