Network Protocols: TCP, UDP, IP, DNS, HTTP/HTTPS & OSI/TCP-IP Models
This post is a comprehensive introduction to network protocols – including TCP, UDP, IP, DNS, HTTP/HTTPS, OSI model and TCP/IP stack with practical examples.
In a Nutshell
Network protocols regulate communication between computers. TCP/IP is the fundamental protocol stack, OSI describes 7 layers, HTTP/HTTPS enable web communication and DNS resolves names to IPs.
Compact Technical Description
Network protocols are standardized rules and conventions for data communication between computers in a network.
Important Protocols:
TCP (Transmission Control Protocol)
- Type: Connection-oriented, reliable
- Features: 3-way handshake, flow control, error correction
- Application: Web, email, file transfer
- Port: 80 (HTTP), 443 (HTTPS), 25 (SMTP)
UDP (User Datagram Protocol)
- Type: Connectionless, unreliable
- Features: Simple, fast, no guarantees
- Application: Streaming, gaming, DNS
- Port: 53 (DNS), 123 (NTP), 67 (DHCP)
IP (Internet Protocol)
- Type: Packet switching, routing
- Versions: IPv4 (32 bit), IPv6 (128 bit)
- Features: Addressing, fragmentation
- Application: Foundation for Internet
DNS (Domain Name System)
- Type: Name resolution
- Function: Domain → IP address
- Record Types: A, AAAA, MX, NS, CNAME
- Port: 53 (UDP/TCP)
HTTP/HTTPS (Hypertext Transfer Protocol)
- Type: Application protocol for web
- Methods: GET, POST, PUT, DELETE
- Status: 200 OK, 404 Not Found, 500 Server Error
- Port: 80 (HTTP), 443 (HTTPS)
Exam-Relevant Key Points
- Network Protocols: Rules for computer-based communication
- TCP: Connection-oriented, reliable, 3-way handshake
- UDP: Connectionless, fast, unreliable, streaming
- IP: Packet switching, routing, IPv4/IPv6
- DNS: Name resolution, domain → IP address
- HTTP/HTTPS: Web communication, request/response
- OSI Model: 7-layer model for network communication
- TCP/IP Stack: 4-layer model, practical implementation
- IHK-relevant: Foundation for network administration and development
Core Components
- OSI Model: Theoretical 7-layer model
- TCP/IP Stack: Practical 4-layer model
- Transport Protocols: TCP, UDP for data transport
- Network Protocols: IP for routing and addressing
- Application Protocols: HTTP, DNS, SMTP for services
- Port Numbers: Identification of services
- Socket Programming: Network communication
- Network Security: Firewalls, VPN, TLS
Practical Examples
1. TCP Socket Programming with Java
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class TCPServerDemo {
private static final int PORT = 8080;
private static final int MAX_CLIENTS = 10;
public static void main(String[] args) {
System.out.println("=== TCP Server Demo ===");
// Thread pool for client connections
ExecutorService threadPool = Executors.newFixedThreadPool(MAX_CLIENTS);
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("TCP Server started on port " + PORT);
while (true) {
// Wait for client connections
Socket clientSocket = serverSocket.accept();
System.out.println("New client connected: " + clientSocket.getInetAddress());
// Handle client in separate thread
threadPool.execute(new ClientHandler(clientSocket));
}
} catch (IOException e) {
System.err.println("Server error: " + e.getMessage());
} finally {
threadPool.shutdown();
}
}
// Client handler
static class ClientHandler implements Runnable {
private final Socket clientSocket;
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
@Override
public void run() {
try (
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true)
) {
String clientAddress = clientSocket.getInetAddress().toString();
System.out.println("Handler for " + clientAddress + " started");
// Send greeting
out.println("Welcome to TCP Server!");
out.println("Type 'exit' to disconnect");
// Receive and respond to messages from client
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Message from " + clientAddress + ": " + inputLine);
if ("exit".equalsIgnoreCase(inputLine.trim())) {
out.println("Goodbye!");
break;
}
// Echo with timestamp
String response = "Echo: " + inputLine + " [" +
java.time.LocalDateTime.now() + "]";
out.println(response);
}
} catch (IOException e) {
System.err.println("Error in client handler: " + e.getMessage());
} finally {
try {
clientSocket.close();
System.out.println("Client connection closed");
} catch (IOException e) {
System.err.println("Error closing connection: " + e.getMessage());
}
}
}
}
// TCP Client
static class TCPClient {
private final String hostname;
private final int port;
public TCPClient(String hostname, int port) {
this.hostname = hostname;
this.port = port;
}
public void start() {
try (
Socket socket = new Socket(hostname, port);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in))
) {
System.out.println("Connected to server");
// Receive server response
String serverResponse = in.readLine();
System.out.println("Server: " + serverResponse);
// Interactive communication
String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
serverResponse = in.readLine();
System.out.println("Server: " + serverResponse);
if ("exit".equalsIgnoreCase(userInput.trim())) {
break;
}
}
} catch (UnknownHostException e) {
System.err.println("Unknown host: " + hostname);
} catch (IOException e) {
System.err.println("I/O error: " + e.getMessage());
}
}
}
// TCP Performance Test
static class TCPPerformanceTest {
public static void testTCPLatency(String hostname, int port, int iterations) {
try (Socket socket = new Socket(hostname, port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
System.out.println("=== TCP Latency Test ===");
long totalTime = 0;
for (int i = 0; i < iterations; i++) {
long startTime = System.nanoTime();
out.println("ping");
String response = in.readLine();
long endTime = System.nanoTime();
long latency = (endTime - startTime) / 1_000_000; // ms
totalTime += latency;
if (i % 10 == 0) {
System.out.printf("Ping %d: %dms%n", i + 1, latency);
}
}
double avgLatency = (double) totalTime / iterations;
System.out.printf("Average latency: %.2fms%n", avgLatency);
} catch (IOException e) {
System.err.println("Error in latency test: " + e.getMessage());
}
}
public static void testTCPThroughput(String hostname, int port, int dataSize) {
try (Socket socket = new Socket(hostname, port);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
System.out.println("=== TCP Throughput Test ===");
// Create test data
StringBuilder testData = new StringBuilder();
for (int i = 0; i < dataSize; i++) {
testData.append("A");
}
long startTime = System.nanoTime();
out.println("throughput:" + testData.toString());
String response = in.readLine();
long endTime = System.nanoTime();
long duration = (endTime - startTime) / 1_000_000; // ms
double throughput = (double) dataSize / (duration / 1000.0) / 1024.0; // KB/s
System.out.printf("Throughput: %.2f KB/s (%d bytes in %dms)%n",
throughput, dataSize, duration);
} catch (IOException e) {
System.err.println("Error in throughput test: " + e.getMessage());
}
}
}
// Main for client tests
public static void main(String[] args) {
// Start server
if (args.length == 0) {
TCPServerDemo.main(args);
} else {
// Client tests
TCPClient client = new TCPClient("localhost", PORT);
// Interactive client
new Thread(() -> client.start()).start();
// Performance tests
try {
Thread.sleep(2000); // Wait until server is ready
TCPPerformanceTest.testTCPLatency("localhost", PORT, 100);
TCPPerformanceTest.testTCPThroughput("localhost", PORT, 10240);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
2. UDP Socket Programming with Python
import socket
import threading
import time
import json
from datetime import datetime
# UDP Server
class UDPServer:
def __init__(self, host='localhost', port=9999):
self.host = host
self.port = port
self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.clients = set()
self.running = False
def start(self):
"""Start of the UDP server"""
self.server_socket.bind((self.host, self.port))
self.running = True
print(f"UDP Server running on {self.host}:{self.port}")
while self.running:
try:
# Receive data
data, client_address = self.server_socket.recvfrom(2048)
# Add client to list
self.clients.add(client_address)
print(f"Message from {client_address}: {data.decode()}")
# Send message to all clients (broadcast)
self.broadcast(data, client_address)
except Exception as e:
print(f"Error receiving: {e}")
def broadcast(self, message, sender_address):
"""Send message to all clients"""
timestamp = datetime.now().strftime("%H:%M:%S")
broadcast_message = f"[{timestamp}] {sender_address[0]}: {message.decode()}"
for client in self.clients:
if client != sender_address:
try:
self.server_socket.sendto(broadcast_message.encode(), client)
except Exception as e:
print(f"Error sending to {client}: {e}")
def stop(self):
"""Stop server"""
self.running = False
self.server_socket.close()
print("UDP Server stopped")
# UDP Client
class UDPClient:
def __init__(self, host='localhost', port=9999):
self.host = host
self.port = port
self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.running = False
def start(self, username):
"""Start of the UDP client"""
self.running = True
print(f"UDP Client connected to {self.host}:{self.port}")
# Start receive thread
receive_thread = threading.Thread(target=self.receive_messages)
receive_thread.daemon = True
receive_thread.start()
try:
while self.running:
# Enter message
message = input(f"{username}: ")
if message.lower() == 'exit':
break
# Send message
full_message = f"{username}: {message}"
self.client_socket.sendto(full_message.encode(), (self.host, self.port))
except KeyboardInterrupt:
print("\nClient terminated")
finally:
self.stop()
def receive_messages(self):
"""Receive messages from server"""
while self.running:
try:
data, server = self.client_socket.recvfrom(2048)
print(f"\r{data.decode()}")
print("Message: ", end="", flush=True)
except Exception as e:
if self.running:
print(f"Error receiving: {e}")
break
def stop(self):
"""Stop client"""
self.running = False
self.client_socket.close()
print("UDP Client stopped")
# UDP Performance Test
class UDPPerformanceTest:
def __init__(self, host='localhost', port=9999):
self.host = host
self.port = port
self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
def test_latency(self, iterations=100):
"""UDP latency test"""
print(f"=== UDP Latency Test ===")
latencies = []
for i in range(iterations):
start_time = time.time()
# Send ping message
self.socket.sendto(b"ping", (self.host, self.port))
# Receive response
try:
data, _ = self.socket.recvfrom(1024)
end_time = time.time()
latency = (end_time - start_time) * 1000 # ms
latencies.append(latency)
if i % 10 == 0:
print(f"Ping {i+1}: {latency:.2f}ms")
except socket.timeout:
print(f"Timeout at ping {i+1}")
if latencies:
avg_latency = sum(latencies) / len(latencies)
min_latency = min(latencies)
max_latency = max(latencies)
print(f"\nLatency statistics:")
print(f" Average: {avg_latency:.2f}ms")
print(f" Minimum: {min_latency:.2f}ms")
print(f" Maximum: {max_latency:.2f}ms")
def test_throughput(self, data_size=1024, duration=5):
"""UDP throughput test"""
print(f"\n=== UDP Throughput Test ===")
# Create test data
test_data = b'A' * data_size
start_time = time.time()
packets_sent = 0
while time.time() - start_time < duration:
try:
self.socket.sendto(test_data, (self.host, self.port))
packets_sent += 0
# Brief pause to not overload server
time.sleep(0.001)
except Exception as e:
print(f"Error sending: {e}")
break
end_time = time.time()
total_time = end_time - start_time
throughput = (packets_sent * data_size) / total_time / 1024 # KB/s
packets_per_second = packets_sent / total_time
print(f"Throughput statistics:")
print(f" Packets sent: {packets_sent}")
print(f" Total duration: {total_time:.2f}s")
print(f" Packets/second: {packets_per_second:.2f}")
print(f" Throughput: {throughput:.2f} KB/s")
def test_packet_loss(self, packets=1000):
"""UDP packet loss test"""
print(f"\n=== UDP Packet Loss Test ===")
packets_lost = 0
for i in range(packets):
try:
# Send sequential number
packet = f"packet_{i}".encode()
self.socket.sendto(packet, (self.host, self.port))
# Brief pause
time.sleep(0.001)
except Exception as e:
packets_lost += 1
loss_rate = (packets_lost / packets) * 100
print(f"Packet loss statistics:")
print(f" Packets sent: {packets}")
print(f" Packets lost: {packets_lost}")
print(f" Loss rate: {loss_rate:.2f}%")
def close(self):
"""Close socket"""
self.socket.close()
# UDP Multicast Demo
class UDPMulticastDemo:
def __init__(self, multicast_group='224.0.0.1', port=5000):
self.multicast_group = multicast_group
self.port = port
def create_multicast_sender(self):
"""Create multicast sender"""
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Set TTL (how many hops the packet is allowed to make)
ttl = struct.pack('b', 1)
sender.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
return sender
def create_multicast_receiver(self):
"""Create multicast receiver"""
receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Bind socket to multicast address
receiver.bind(('', self.port))
# Join the multicast group
group = socket.inet_aton(self.multicast_group)
receiver.setsockopt(socket.SOL_IP, socket.IP_ADD_MEMBERSHIP, group + socket.inet_aton('0.0.0.0'))
return receiver
def send_multicast(self, message):
"""Send multicast message"""
sender = self.create_multicast_sender()
try:
sender.sendto(message.encode(), (self.multicast_group, self.port))
print(f"Multicast sent: {message}")
finally:
sender.close()
def receive_multicast(self):
"""Receive multicast messages"""
receiver = self.create_multicast_receiver()
try:
print(f"Multicast receiver listening on {self.multicast_group}:{self.port}")
while True:
try:
data, address = receiver.recvfrom(1024)
print(f"Multicast from {address}: {data.decode()}")
except KeyboardInterrupt:
break
finally:
# Leave group
group = socket.inet_aton(self.multicast_group)
receiver.setsockopt(socket.SOL_IP, socket.IP_DROP_MEMBERSHIP, group + socket.inet_aton('0.0.0.0'))
receiver.close()
# Main for UDP demos
def main():
import sys
if len(sys.argv) > 1:
mode = sys.argv[1]
if mode == "server":
# Start UDP server
server = UDPServer()
try:
server.start()
except KeyboardInterrupt:
server.stop()
elif mode == "client":
# Start UDP client
username = input("Your name: ")
client = UDPClient()
client.start(username)
elif mode == "performance":
# Performance tests
test = UDPPerformanceTest()
test.test_latency(100)
test.test_throughput(1024, 5)
test.test_packet_loss(1000)
test.close()
elif mode == "multicast_send":
# Multicast sender
multicast = UDPMulticastDemo()
while True:
message = input("Multicast message (or 'exit'): ")
if message.lower() == 'exit':
break
multicast.send_multicast(message)
elif mode == "multicast_receive":
# Multicast receiver
multicast = UDPMulticastDemo()
multicast.receive_multicast()
else:
print("Usage: python udp_demo.py [server|client|performance|multicast_send|multicast_receive]")
else:
print("Usage: python udp_demo.py [server|client|performance|multicast_send|multicast_receive]")
if __name__ == "__main__":
main()
3. DNS Queries with Different Programming Languages
import java.net.*;
import java.util.*;
public class DNSLookupDemo {
// Simple DNS query
public static String dnsLookup(String hostname) {
try {
InetAddress address = InetAddress.getByName(hostname);
return address.getHostAddress();
} catch (UnknownHostException e) {
return "Unknown host: " + hostname;
}
}
// Reverse DNS query (IP → Hostname)
public static String reverseDNSLookup(String ipAddress) {
try {
InetAddress address = InetAddress.getByName(ipAddress);
return address.getHostName();
} catch (UnknownHostException e) {
return "Unknown IP: " + ipAddress;
}
}
// All IP addresses for a hostname
public static List<String> getAllIPAddresses(String hostname) {
List<String> addresses = new ArrayList<>();
try {
InetAddress[] allAddresses = InetAddress.getAllByName(hostname);
for (InetAddress addr : allAddresses) {
addresses.add(addr.getHostAddress());
}
} catch (UnknownHostException e) {
addresses.add("Unknown host: " + hostname);
}
return addresses;
}
// Query DNS record types (simplified)
public static void dnsLookupWithTypes(String hostname) {
System.out.println("=== DNS Lookup for " + hostname + " ===");
// A record (IPv4)
String ipv4 = dnsLookup(hostname);
System.out.println("A record (IPv4): " + ipv4);
// AAAA record (IPv6)
try {
InetAddress ipv6Address = InetAddress.getByName(hostname);
if (ipv6Address instanceof Inet6Address) {
System.out.println("AAAA record (IPv6): " + ipv6Address.getHostAddress());
}
} catch (UnknownHostException e) {
System.out.println("AAAA record (IPv6): Not found");
}
// Reverse lookup
if (!ipv4.equals("Unknown host: " + hostname)) {
String reverse = reverseDNSLookup(ipv4);
System.out.println("PTR record (Reverse): " + reverse);
}
// MX records (Mail Exchange)
dnsLookupMX(hostname);
// NS records (Name Server)
dnsLookupNS(hostname);
}
// Query MX records
public static void dnsLookupMX(String hostname) {
try {
// In practice, one would use DNS libraries like dnsjava
// Here we demonstrate the concept
System.out.println("MX records: Uses DNS libraries for complete query");
// Example with simple logic
if (hostname.endsWith(".com")) {
System.out.println(" MX: mail." + hostname + " (Example)");
}
} catch (Exception e) {
System.out.println("MX records: Error during query - " + e.getMessage());
}
}
// Query NS records
public static void dnsLookupNS(String hostname) {
try {
System.out.println("NS records: Uses DNS libraries for complete query");
// Example with simple logic
String[] commonNS = {"ns1." + hostname, "ns2." + hostname};
for (String ns : commonNS) {
System.out.println(" NS: " + ns + " (Example)");
}
} catch (Exception e) {
System.out.println("NS records: Error during query - " + e.getMessage());
}
}
// DNS performance test
public static void dnsPerformanceTest(String hostname, int iterations) {
System.out.println("=== DNS Performance Test ===");
long totalTime = 0;
int successfulLookups = 0;
for (int i = 0; i < iterations; i++) {
long startTime = System.nanoTime();
String result = dnsLookup(hostname);
long endTime = System.nanoTime();
long duration = (endTime - startTime) / 1_000_000; // ms
if (!result.startsWith("Unknown host")) {
totalTime += duration;
successfulLookups++;
}
if (i % 10 == 0) {
System.out.printf("Lookup %d: %dms%n", i + 1, duration);
}
}
if (successfulLookups > 0) {
double avgTime = (double) totalTime / successfulLookups;
System.out.printf("Average DNS lookup time: %.2fms%n", avgTime);
System.out.printf("Successful lookups: %d/%d%n", successfulLookups, iterations);
}
}
// DNS caching demo
public static void dnsCachingDemo(String hostname) {
System.out.println("=== DNS Caching Demo ===");
// First lookup (cache miss)
long start = System.nanoTime();
String result1 = dnsLookup(hostname);
long firstLookup = (System.nanoTime() - start) / 1_000_000;
// Second lookup (cache hit)
start = System.nanoTime();
String result2 = dnsLookup(hostname);
long secondLookup = (System.nanoTime() - start) / 1_000_000;
System.out.println("First lookup: " + firstLookup + "ms");
System.out.println("Second lookup: " + secondLookup + "ms");
if (secondLookup < firstLookup) {
System.out.println("DNS caching active (second lookup faster)");
} else {
System.out.println("No DNS caching detected");
}
// Compare results
System.out.println("Result 1: " + result1);
System.out.println("Result 2: " + result2);
System.out.println("Results equal: " + result1.equals(result2));
}
// IPv6 support test
public static void ipv6SupportTest(String hostname) {
System.out.println("=== IPv6 Support Test ===");
try {
// Resolve IPv6 address
InetAddress[] addresses = InetAddress.getAllByName(hostname);
boolean hasIPv4 = false;
boolean hasIPv6 = false;
for (InetAddress addr : addresses) {
if (addr instanceof Inet4Address) {
hasIPv4 = true;
System.out.println("IPv4: " + addr.getHostAddress());
} else if (addr instanceof Inet6Address) {
hasIPv6 = true;
System.out.println("IPv6: " + addr.getHostAddress());
}
}
System.out.println("IPv4 support: " + (hasIPv4 ? "Yes" : "No"));
System.out.println("IPv6 support: " + (hasIPv6 ? "Yes" : "No"));
} catch (UnknownHostException e) {
System.out.println("IPv6 support test failed: " + e.getMessage());
}
}
public static void main(String[] args) {
String hostname = "google.com";
if (args.length > 0) {
hostname = args[0];
}
// Various DNS queries
dnsLookupWithTypes(hostname);
// Performance test
dnsPerformanceTest(hostname, 50);
// Caching demo
dnsCachingDemo(hostname);
// IPv6 support test
ipv6SupportTest(hostname);
}
}
4. HTTP/HTTPS Client with various features
import requests
import json
import time
import ssl
import urllib3
from urllib3.util.retry import Retry
from datetime import datetime
# HTTP Client with advanced features
class HTTPClient:
def __init__(self):
self.session = requests.Session()
self.setup_session()
def setup_session(self):
"""Configure session"""
# Retry strategy
retry_strategy = Retry(
total=3,
backoff_factor=1,
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["HEAD", "GET", "OPTIONS"]
)
adapter = urllib3.HTTPAdapter(max_retries=retry_strategy)
self.session.mount("https://", adapter)
self.session.mount("http://", adapter)
# Headers
self.session.headers.update({
'User-Agent': 'HTTPClient-Demo/1.0',
'Accept': 'application/json',
'Accept-Language': 'de-DE,de;q=0.9,en;q=0.8',
'Cache-Control': 'no-cache'
})
# Timeout
self.session.timeout = 30
print("HTTP Client configured")
def get_request(self, url, params=None):
"""GET request with error handling"""
try:
print(f"GET Request: {url}")
start_time = time.time()
response = self.session.get(url, params=params)
end_time = time.time()
self.print_response_info(response, end_time - start_time)
return response
except requests.exceptions.RequestException as e:
print(f"GET Request failed: {e}")
return None
def post_request(self, url, data=None, json_data=None):
"""POST request with data"""
try:
print(f"POST Request: {url}")
if json_data:
print(f"JSON data: {json.dumps(json_data, indent=2)}")
start_time = time.time()
if json_data:
response = self.session.post(url, json=json_data)
else:
response = self.session.post(url, data=data)
end_time = time.time()
self.print_response_info(response, end_time - start_time)
return response
except requests.exceptions.RequestException as e:
print(f"POST Request failed: {e}")
return None
def print_response_info(self, response, duration):
"""Print response information"""
print(f"Status Code: {response.status_code}")
print(f"Response Time: {duration:.2f}s")
print(f"Content-Type: {response.headers.get('Content-Type', 'N/A')}")
print(f"Content-Length: {response.headers.get('Content-Length', 'N/A')}")
# Print headers
if response.headers:
print("Response Headers:")
for key, value in response.headers.items():
print(f" {key}: {value}")
def test_http_methods(self, url):
"""Test various HTTP methods"""
print(f"=== HTTP Methods Test for {url} ===")
# GET
print("\n--- GET ---")
response = self.get_request(url)
# HEAD
print("\n--- HEAD ---")
try:
response = self.session.head(url)
print(f"HEAD Status: {response.status_code}")
print(f"HEAD Headers: {dict(response.headers)}")
except Exception as e:
print(f"HEAD Request failed: {e}")
# OPTIONS
print("\n--- OPTIONS ---")
try:
response = self.session.options(url)
print(f"OPTIONS Status: {response.status_code}")
allowed_methods = response.headers.get('Allow', 'N/A')
print(f"Allowed methods: {allowed_methods}")
except Exception as e:
print(f"OPTIONS Request failed: {e}")
def test_https_features(self, url):
"""Test HTTPS features"""
print(f"=== HTTPS Features Test for {url} ===")
try:
# SSL certificate information
response = self.session.get(url)
# Print SSL information
cert_info = response.raw._connection.peer.cert
if cert_info:
print("SSL Certificate Information:")
for cert in cert_info:
print(f" Subject: {cert.subject}")
print(f" Issuer: {cert.issuer}")
print(f" Valid from: {cert.not_valid_before}")
print(f" Valid until: {cert.not_valid_after}")
print(f" Serial: {cert.serial_number}")
# TLS version
tls_version = response.raw._connection.tls_version
print(f"TLS Version: {tls_version}")
# Cipher Suite
cipher_suite = response.raw._connection.cipher
print(f"Cipher Suite: {cipher_suite}")
except Exception as e:
print(f"HTTPS Features Test failed: {e}")
def test_authentication(self, url, username, password):
"""Test HTTP authentication"""
print(f"=== Authentication Test for {url} ===")
# Basic Authentication
try:
from requests.auth import HTTPBasicAuth
auth = HTTPBasicAuth(username, password)
response = self.session.get(url, auth=auth)
print(f"Basic Auth Status: {response.status_code}")
if response.status_code == 200:
print("Basic Authentication successful")
else:
print("Basic Authentication failed")
except Exception as e:
print(f"Authentication Test failed: {e}")
def test_cookies(self, url):
"""Test cookie handling"""
print(f"=== Cookie Test for {url} ===")
try:
# First request without cookies
response1 = self.session.get(url)
print(f"First request status: {response1.status_code}")
print(f"Cookies after first request: {len(self.session.cookies)}")
# Second request with cookies
response2 = self.session.get(url)
print(f"Second request status: {response2.status_code}")
print(f"Cookies after second request: {len(self.session.cookies)}")
# Cookie information
if self.session.cookies:
print("Cookie Details:")
for cookie in self.session.cookies:
print(f" {cookie.name}: {cookie.value}")
print(f" Domain: {cookie.domain}")
print(f" Path: {cookie.path}")
print(f" Secure: {cookie.secure}")
print(f" HttpOnly: {cookie.has_attr('HttpOnly')}")
except Exception as e:
print(f"Cookie Test failed: {e}")
def test_redirects(self, url):
"""Test redirect handling"""
print(f"=== Redirect Test for {url} ===")
try:
# Do not follow redirects
response = self.session.get(url, allow_redirects=False)
print(f"Status without redirects: {response.status_code}")
if 300 <= response.status_code < 400:
location = response.headers.get('Location', 'N/A')
print(f"Redirect to: {location}")
# Follow redirects
response = self.session.get(url, allow_redirects=True)
print(f"Status with redirects: {response.status_code}")
print(f"Final URL: {response.url}")
# Redirect history
if hasattr(response.history, '__iter__'):
print("Redirect History:")
for i, resp in enumerate(response.history):
print(f" {i+1}. {resp.status_code} -> {resp.url}")
except Exception as e:
print(f"Redirect Test failed: {e}")
def test_download(self, url, save_path=None):
"""Test file download"""
print(f"=== Download Test for {url} ===")
try:
response = self.session.get(url, stream=True)
content_length = int(response.headers.get('content-length', 0))
print(f"File size: {content_length} bytes")
if save_path:
with open(save_path, 'wb') as f:
downloaded = 0
chunk_size = 8192
for chunk in response.iter_content(chunk_size=chunk_size):
f.write(chunk)
downloaded += chunk_size
# Show progress
progress = (downloaded / content_length) * 100 if content_length > 0 else 0
print(f"\rDownload: {progress:.1f}%", end="", flush=True)
print(f"\nFile saved: {save_path}")
except Exception as e:
print(f"Download failed: {e}")
def performance_test(self, url, iterations=10):
"""Performance test"""
print(f"=== Performance Test for {url} ===")
times = []
for i in range(iterations):
try:
start_time = time.time()
response = self.session.get(url)
end_time = time.time()
duration = end_time - start_time
times.append(duration)
if i % 5 == 0:
print(f"Request {i+1}: {duration:.3f}s")
except Exception as e:
print(f"Request {i+1} failed: {e}")
if times:
avg_time = sum(times) / len(times)
min_time = min(times)
max_time = max(times)
print(f"\nPerformance Statistics:")
print(f" Requests: {len(times)}")
print(f" Average: {avg_time:.3f}s")
print(f" Minimum: {min_time:.3f}s")
print(f" Maximum: {max_time:.3f}s")
print(f" Requests/Second: {1/avg_time:.2f}")
# API Client for REST APIs
class APIClient(HTTPClient):
def __init__(self, base_url):
super().__init__()
self.base_url = base_url.rstrip('/')
# API-specific headers
self.session.headers.update({
'Content-Type': 'application/json',
'Accept': 'application/json'
})
def get_resource(self, resource, params=None):
"""GET resource"""
url = f"{self.base_url}/{resource.lstrip('/')}"
return self.get_request(url, params)
def create_resource(self, resource, data):
"""POST resource"""
url = f"{self.base_url}/{resource.lstrip('/')}"
return self.post_request(url, json_data=data)
def update_resource(self, resource, data):
"""PUT resource"""
url = f"{self.base_url}/{resource.lstrip('/')}"
try:
response = self.session.put(url, json=data)
self.print_response_info(response, 0)
return response
except Exception as e:
print(f"PUT Request failed: {e}")
return None
def delete_resource(self, resource):
"""DELETE resource"""
url = f"{self.base_url}/{resource.lstrip('/')}"
try:
response = self.session.delete(url)
self.print_response_info(response, 0)
return response
except Exception as e:
print(f"DELETE Request failed: {e}")
return None
# Main for HTTP demos
def main():
import sys
# HTTP Client Demo
client = HTTPClient()
# HTTP methods test
client.test_http_methods("https://httpbin.org")
# HTTPS features test
client.test_https_features("https://google.com")
# Redirect test
client.test_redirects("http://httpbin.org/redirect/1")
# Cookie test
client.test_cookies("https://httpbin.org/cookies/set/test/value")
# Performance test
client.performance_test("https://httpbin.org/get", 20)
# API Client Demo
api_client = APIClient("https://jsonplaceholder.typicode.com")
# GET Users
users_response = api_client.get_resource("/users")
if users_response:
print(f"Users: {users_response.json()}")
# Create Post
new_post = {
"title": "Test Post",
"body": "Test Body",
"userId": 1
}
create_response = api_client.create_resource("/posts", new_post)
# Download test
client.test_download("https://httpbin.org/bytes/1024", "test_download.bin")
if __name__ == "__main__":
main()
OSI Model vs TCP/IP Stack
OSI Model (7 Layers)
| Layer | Name | Function | Examples |
|---|---|---|---|
| 7 | Application | Application protocols | HTTP, FTP, SMTP |
| 6 | Presentation | Data conversion | SSL/TLS, JPEG |
| 5 | Session | Session management | NetBIOS, RPC |
| 4 | Transport | End-to-End communication | TCP, UDP |
| 3 | Network | Routing and addressing | IP, ICMP |
| 2 | Data Link | Frame transmission | Ethernet, WiFi |
| 1 | Physical | Bit transmission | Cable, Radio |
TCP/IP Stack (4 Layers)
| Layer | Name | OSI Equivalent | Protocols |
|---|---|---|---|
| 4 | Application | 5-7 | HTTP, FTP, DNS |
| 3 | Transport | 4 | TCP, UDP |
| 2 | Internet | 3 | IP, ICMP |
| 1 | Network Access | 1-2 | Ethernet, WiFi |
Important Port Numbers
Well-Known Ports (0-1023)
| Port | Protocol | Service |
|---|---|---|
| 20 | FTP | File Transfer (Data) |
| 21 | FTP | File Transfer (Control) |
| 22 | SSH | Secure Shell |
| 23 | Telnet | Remote Terminal |
| 25 | SMTP | |
| 53 | DNS | Domain Name System |
| 80 | HTTP | Web (unencrypted) |
| 110 | POP3 | E-Mail (Post Office) |
| 143 | IMAP | E-Mail (Internet Message) |
| 443 | HTTPS | Web (encrypted) |
| 993 | IMAPS | IMAP over SSL |
| 995 | POP3S | POP3 over SSL |
Registered Ports (1024-49151)
| Port | Protocol | Service |
|---|---|---|
| 3306 | MySQL | Database |
| 5432 | PostgreSQL | Database |
| 8080 | HTTP-Alt | Web (alternative) |
| 8443 | HTTPS-Alt | Web (alternative) |
| 27017 | MongoDB | NoSQL Database |
TCP vs UDP Comparison
| Property | TCP | UDP |
|---|---|---|
| Connection | Connection-oriented | Connectionless |
| Reliability | Guaranteed | Not guaranteed |
| Order | Guaranteed | Not guaranteed |
| Flow Control | Yes | No |
| Error Correction | Yes | No |
| Overhead | High | Low |
| Speed | Slower | Faster |
| Application | Web, E-Mail | Streaming, Gaming |
HTTP Status Codes Overview
1xx Informational
- 100 Continue: Continue
- 101 Switching Protocols: Protocol switch
2xx Success
- 200 OK: Successful
- 201 Created: Created
- 204 No Content: No content
3xx Redirection
- 301 Moved Permanently: Permanently moved
- 302 Found: Temporarily moved
- 304 Not Modified: Not modified
4xx Client Error
- 400 Bad Request: Invalid request
- 401 Unauthorized: Not authorized
- 403 Forbidden: Forbidden
- 404 Not Found: Not found
- 429 Too Many Requests: Too many requests
5xx Server Error
- 500 Internal Server Error: Internal server error
- 502 Bad Gateway: Gateway error
- 503 Service Unavailable: Service unavailable
DNS Record Types
| Type | Description | Example |
|---|---|---|
| A | IPv4 address | example.com → 93.184.216.34 |
| AAAA | IPv6 address | example.com → 2606:2800:220:1 |
| MX | Mail Exchange | example.com → mail.example.com |
| NS | Name Server | example.com → ns1.example.com |
| CNAME | Canonical Name | www.example.com → example.com |
| TXT | Text information | example.com → “v=spf1 include:_spf.google.com ~all” |
| PTR | Pointer (Reverse) | 93.184.216.34 → example.com |
Socket Programming Basics
TCP Socket Lifecycle
// Server
1. Create ServerSocket
2. Wait for connection (accept)
3. Create InputStream/OutputStream
4. Exchange data
5. Close connection
// Client
1. Create Socket
2. Connect to server
3. Create InputStream/OutputStream
4. Exchange data
5. Close connection
UDP Socket Lifecycle
// Server
1. Create DatagramSocket
2. Wait for packets (receive)
3. Process packet
4. Send response (send)
// Client
1. Create DatagramSocket
2. Send packet (send)
3. Wait for response (receive)
4. Close socket
Advantages and Disadvantages
Advantages of Network Protocols
- Standardization: Interoperability between systems
- Scalability: Support for large networks
- Reliability: Error handling and recovery
- Flexibility: Different protocols for different purposes
Disadvantages
- Complexity: Many layers and protocols
- Overhead: Additional data for protocol information
- Security: Attack surface for hackers
- Performance: Network latencies
Common Exam Questions
-
What is the difference between TCP and UDP? TCP is connection-oriented and reliable, UDP is connectionless and fast but unreliable.
-
Explain the OSI model! The OSI model describes 7 layers for network communication from Physical to Application.
-
What is DNS and how does it work? DNS translates domain names into IP addresses and vice versa via hierarchical name servers.
-
When do you use HTTP vs HTTPS? HTTP for unencrypted communication, HTTPS for encrypted communication with SSL/TLS.
Most Important Sources
- https://www.ietf.org/rfc/rfc791.html (TCP)
- https://www.ietf.org/rfc/rfc768.html (UDP)
- https://www.ietf.org/rfc/rfc1035.html (DNS)
- https://www.ietf.org/rfc/rfc2616.html (HTTP/1.1)