Skip to content
IRC-CodingIRC-Coding
Сетевые протоколыTCP UDP IPDNS HTTP HTTPSOSI-модельTCP/IP-стек

Сетевые протоколы: TCP, UDP, IP, DNS, HTTP/HTTPS

Основы сетевых протоколов TCP, UDP, IP, DNS, HTTP/HTTPS. OSI-модель и TCP/IP-стек с практическими примерами.

S

schutzgeist

24 min read
Сетевые протоколы: TCP, UDP, IP, DNS, HTTP/HTTPS

Сетевые протоколы: TCP, UDP, IP, DNS, HTTP/HTTPS и модели OSI/TCP-IP

Этот материал представляет собой полное введение в сетевые протоколы с разбором TCP, UDP, IP, DNS, HTTP/HTTPS, модели OSI и стека TCP/IP с практическими примерами.

В двух словах

Сетевые протоколы задают правила обмена данными между компьютерами. TCP/IP — это базовый стек протоколов, модель OSI описывает 7 уровней, HTTP/HTTPS обеспечивают веб-коммуникацию, а DNS преобразует имена доменов в IP-адреса.

Краткое описание

Сетевые протоколы — это стандартизированные правила и соглашения для обмена данными между компьютерами в сети.

Основные протоколы:

TCP (Transmission Control Protocol)

  • Тип: ориентирован на подключение, надежный
  • Особенности: трёхшаговое рукопожатие, управление потоком, исправление ошибок
  • Применение: веб, электронная почта, передача файлов
  • Порты: 80 (HTTP), 443 (HTTPS), 25 (SMTP)

UDP (User Datagram Protocol)

  • Тип: без установления соединения, ненадежный
  • Особенности: простой, быстрый, без гарантий
  • Применение: потоковая передача, игры, DNS
  • Порты: 53 (DNS), 123 (NTP), 67 (DHCP)

IP (Internet Protocol)

  • Тип: коммутация пакетов, маршрутизация
  • Версии: IPv4 (32 бита), IPv6 (128 бит)
  • Особенности: адресация, фрагментация
  • Применение: основа интернета

DNS (Domain Name System)

  • Тип: разрешение имен
  • Функция: доменное имя → IP-адрес
  • Типы записей: A, AAAA, MX, NS, CNAME
  • Порт: 53 (UDP/TCP)

HTTP/HTTPS (Hypertext Transfer Protocol)

  • Тип: прикладной протокол для веба
  • Методы: GET, POST, PUT, DELETE
  • Коды состояния: 200 OK, 404 Not Found, 500 Server Error
  • Порты: 80 (HTTP), 443 (HTTPS)

Информация для экзамена

Эти пункты — основа экзаменационной подготовки по ИТ-специальностям. На экзамене требуется не только назвать термины, но и объяснить различия, привести примеры применения и установить связи между концепциями.

  • Сетевые протоколы: правила компьютерного взаимодействия. Объяснение: без стандартизированных протоколов разные системы не смогли бы общаться. Протоколы определяют формат данных, порядок их передачи, обработку ошибок и подтверждение получения.
  • TCP: ориентирован на подключение, надежный, трёхшаговое рукопожатие (SYN → SYN-ACK → ACK). Объяснение: TCP гарантирует полную и корректную доставку данных. На экзамене нужно объяснить этапы рукопожатия и знать, когда применяется TCP (веб, электронная почта, FTP).
  • UDP: без соединения, быстрый, ненадежный. Объяснение: UDP отправляет данные без установления соединения и без подтверждения приема. На экзамене следует четко контрастировать с TCP и назвать приложения, где скорость важнее надежности (DNS, VoIP, игры, потоковая передача).
  • IP: коммутация пакетов, маршрутизация, IPv4 (32 бита) или IPv6 (128 бит). Объяснение: IP — фундамент интернета. Нужно объяснить разницу между IPv4 (ограниченное число адресов, требуется NAT) и IPv6 (практически неограниченные адреса) и понимать, как маршрутизаторы пересылают пакеты.
  • DNS: разрешение имен, преобразование доменов в IP-адреса. Объяснение: DNS переводит понятные людям имена в компьютерные адреса. На экзамене нужно объяснить иерархическую структуру (корневой сервер → сервер TLD → авторитативный сервер) и типы записей (A, AAAA, MX, CNAME).
  • HTTP/HTTPS: веб-коммуникация, запрос/ответ. Объяснение: требуется объяснить методы (GET, POST, PUT, DELETE) и коды состояния (200, 404, 500), а также разницу между HTTP (порт 80, без шифрования) и HTTPS (порт 443, TLS).
  • Модель OSI: семиуровневая модель. Объяснение: на экзамене нужно назвать уровни и приводить примеры: уровень 2 = канальный (коммутатор), уровень 3 = сетевой (маршрутизатор, IP), уровень 4 = транспортный (TCP, UDP), уровень 7 = прикладной (HTTP, DNS).
  • Стек TCP/IP: четырёхуровневая модель. Объяснение: TCP/IP — модель, используемая практически в интернете. Следует уметь сопоставлять 4 уровня TCP/IP с 7 уровнями OSI (например, прикладной уровень TCP/IP соответствует уровням 5-7 в OSI).
  • Экзаменационная значимость: основа для администрирования и разработки сетей. Объяснение: в экзаменах регулярно проверяют знание сетей, протоколов и безопасности. Систематическое изучение помогает глубже разобраться в материале.

Ключевые компоненты

Ключевые компоненты формируют техническую основу сетевого взаимодействия. Понимание этих элементов позволяет не просто описывать протоколы, но и анализировать сетевые проблемы, разрабатывать собственные приложения.

  1. Модель OSI: теоретическая семиуровневая модель. Почему это важно: модель OSI создает единый язык для описания сетевого взаимодействия. Когда коллега говорит “проблема на уровне 3”, сразу понятно, что дело в маршрутизации или IP. Это помогает систематически локализовать ошибки.
  2. Стек TCP/IP: практическая четырёхуровневая модель. Почему это важно: TCP/IP — именно та модель, которая работает в интернете. Она проще, чем OSI, и напрямую реализуется в коде. Поняв TCP/IP, поймешь, как интернет действительно устроен.
  3. Транспортные протоколы: TCP и UDP для передачи данных. Почему это важно: выбор транспортного протокола определяет надежность общения приложения. Банковское приложение требует TCP, прямая трансляция требует UDP. Как разработчик, ты принимаешь это решение.
  4. Сетевые протоколы: IP для маршрутизации и адресации. Почему это важно: IP-адреса — это как почтовые адреса в сети. Без правильной адресации данные не доходят. Переход с IPv4 на IPv6 — актуальная задача во многих организациях.
  5. Прикладные протоколы: HTTP, DNS, SMTP для сервисов. Почему это важно: эти протоколы — интерфейс между пользователем и сетью. Каждый запрос страницы использует HTTP, каждое доменное имя требует DNS. Как разработчик, ты работаешь с ними каждый день.
  6. Номера портов: идентификация сервисов. Почему это важно: одного IP-адреса недостаточно, потому что на одном сервере одновременно работают несколько сервисов. Порты (например, 80 для HTTP, 443 для HTTPS) направляют трафик нужной программе. На экзамене нужно знать стандартные порты.
  7. Программирование с использованием сокетов: сетевое взаимодействие. Почему это важно: сокеты — программный интерфейс для работы с сетями. Кто понимает сокеты, может писать собственные серверы и клиенты, что отличает настоящего разработчика от обычного пользователя.
  8. Сетевая безопасность: файрволы, VPN, TLS. Почему это важно: открытая сеть — цель для атак. TLS шифрует данные, файрволы блокируют нежелательный трафик. На экзамене и на работе безопасность — не опция, а обязательное требование.

Практические примеры

1. Программирование TCP сокетов на Java

Что делает этот код? Программа на Java демонстрирует полноценный TCP-сервер с управлением потоками, способный одновременно обслуживать нескольких клиентов. Включены также TCP-клиент и тесты производительности для измерения задержки и пропускной способности.

Зачем это понимать? TCP — самый распространенный транспортный протокол в интернете. Понимая структуру TCP-сервера, поймешь, как работают веб-серверы, почтовые серверы и базы данных на фундаментальном уровне. Трёхшаговое рукопожатие, управление соединениями и обработка потоков — ключевые концепции для экзамена и практической работы.

Чему можно научиться?

  • Как ServerSocket принимает соединения и запускает их в отдельных потоках
  • Как обмениваться данными в обе стороны с помощью BufferedReader и PrintWriter
  • Почему пул потоков важен, чтобы не создавать тысячи отдельных потоков
  • Как программно измерять задержку и пропускную способность
  • Как корректно закрывать клиентские соединения и освобождать ресурсы

Если Java не твой основной язык или ты её не изучал, всё равно прочитай этот пример, но сосредоточься на структуре. Когда инициализируются глобальные переменные, когда устанавливается сам клиент/соединение, когда появляются блоки try и почему именно там. Ниже найдешь также пример на Python.

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 для Client-Verbindungen
        ExecutorService threadPool = Executors.newFixedThreadPool(MAX_CLIENTS);
        
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("TCP Server gestartet auf Port " + PORT);
            
            while (true) {
                // Auf Client-Verbindungen warten
                Socket clientSocket = serverSocket.accept();
                System.out.println("Neuer Client verbunden: " + clientSocket.getInetAddress());
                
                // Client in separatem Thread behandeln
                threadPool.execute(new ClientHandler(clientSocket));
            }
            
        } catch (IOException e) {
            System.err.println("Server-Fehler: " + 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 für " + clientAddress + " gestartet");
                
                // Begrüßung senden
                out.println("Willkommen beim TCP Server!");
                out.println("Type 'exit' to disconnect");
                
                // Nachrichten vom Client empfangen und beantworten
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    System.out.println("Nachricht von " + clientAddress + ": " + inputLine);
                    
                    if ("exit".equalsIgnoreCase(inputLine.trim())) {
                        out.println("Goodbye!");
                        break;
                    }
                    
                    // Echo mit Timestamp
                    String response = "Echo: " + inputLine + " [" + 
                                   java.time.LocalDateTime.now() + "]";
                    out.println(response);
                }
                
            } catch (IOException e) {
                System.err.println("Fehler bei Client-Handler: " + e.getMessage());
            } finally {
                try {
                    clientSocket.close();
                    System.out.println("Client-Verbindung geschlossen");
                } catch (IOException e) {
                    System.err.println("Fehler beim Schließen der Verbindung: " + 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("Mit Server verbunden");
                
                // Server-Antwort empfangen
                String serverResponse = in.readLine();
                System.out.println("Server: " + serverResponse);
                
                // Interaktive Kommunikation
                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("Unbekannter Host: " + hostname);
            } catch (IOException e) {
                System.err.println("I/O Fehler: " + 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("Durchschnittliche Latenz: %.2fms%n", avgLatency);
                
            } catch (IOException e) {
                System.err.println("Fehler bei Latenz-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 ===");
                
                // Testdaten erstellen
                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("Durchsatz: %.2f KB/s (%d Bytes in %dms)%n", 
                                 throughput, dataSize, duration);
                
            } catch (IOException e) {
                System.err.println("Fehler bei Throughput-Test: " + e.getMessage());
            }
        }
    }
    
    // Main für Client-Tests
    public static void main(String[] args) {
        // Server starten
        if (args.length == 0) {
            TCPServerDemo.main(args);
        } else {
            // Client-Tests
            TCPClient client = new TCPClient("localhost", PORT);
            
            // Interaktiver Client
            new Thread(() -> client.start()).start();
            
            // Performance Tests
            try {
                Thread.sleep(2000); // Warten bis Server bereit
                TCPPerformanceTest.testTCPLatency("localhost", PORT, 100);
                TCPPerformanceTest.testTCPThroughput("localhost", PORT, 10240);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

2. UDP Socket-программирование с Python

Что делает этот код? Программа демонстрирует UDP-сервер с функцией broadcast, интерактивный UDP-клиент, тесты производительности для измерения задержки, пропускной способности и потерь пакетов, а также пример UDP Multicast.

Зачем это понимать? UDP противоположен TCP: быстрый, но ненадёжный. Понимая UDP, ты узнаешь, когда скорость важнее надёжности. Broadcast и Multicast являются фундаментальными концепциями для обнаружения сетей, потокового вещания и IoT-коммуникации. На экзамене тебе нужно уметь сравнивать TCP и UDP.

Что ты выучишь?

  • Как создавать UDP-сокеты с socket.SOCK_DGRAM
  • Почему UDP не требует установления соединения и как recvfrom возвращает адреса отправителей
  • Как работает broadcast ко всем клиентам и multicast к группе
  • Почему UDP теряет пакеты и как это измерить
  • Как использовать потоки для одновременной отправки и приёма данных

Обрати особое внимание на структуру примера. Разберись с импортами детально и подумай, зачем они нужны и где они используются.

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 des UDP Servers"""
        self.server_socket.bind((self.host, self.port))
        self.running = True
        print(f"UDP Server läuft auf {self.host}:{self.port}")
        
        while self.running:
            try:
                # Daten empfangen
                data, client_address = self.server_socket.recvfrom(2048)
                
                # Client zur Liste hinzufügen
                self.clients.add(client_address)
                
                print(f"Nachricht von {client_address}: {data.decode()}")
                
                # Nachricht an alle Clients senden (Broadcast)
                self.broadcast(data, client_address)
                
            except Exception as e:
                print(f"Fehler beim Empfangen: {e}")
    
    def broadcast(self, message, sender_address):
        """Nachricht an alle Clients senden"""
        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"Fehler beim Senden an {client}: {e}")
    
    def stop(self):
        """Server stoppen"""
        self.running = False
        self.server_socket.close()
        print("UDP Server gestoppt")

# 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 des UDP Clients"""
        self.running = True
        print(f"UDP Client verbunden mit {self.host}:{self.port}")
        
        # Empfangs-Thread starten
        receive_thread = threading.Thread(target=self.receive_messages)
        receive_thread.daemon = True
        receive_thread.start()
        
        try:
            while self.running:
                # Nachricht eingeben
                message = input(f"{username}: ")
                
                if message.lower() == 'exit':
                    break
                
                # Nachricht senden
                full_message = f"{username}: {message}"
                self.client_socket.sendto(full_message.encode(), (self.host, self.port))
                
        except KeyboardInterrupt:
            print("\nClient beendet")
        finally:
            self.stop()
    
    def receive_messages(self):
        """Nachrichten vom Server empfangen"""
        while self.running:
            try:
                data, server = self.client_socket.recvfrom(2048)
                print(f"\r{data.decode()}")
                print("Nachricht: ", end="", flush=True)
                
            except Exception as e:
                if self.running:
                    print(f"Fehler beim Empfangen: {e}")
                break
    
    def stop(self):
        """Client stoppen"""
        self.running = False
        self.client_socket.close()
        print("UDP Client gestoppt")

# 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 Latenz Test"""
        print(f"=== UDP Latency Test ===")
        
        latencies = []
        
        for i in range(iterations):
            start_time = time.time()
            
            # Ping-Nachricht senden
            self.socket.sendto(b"ping", (self.host, self.port))
            
            # Antwort empfangen
            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 bei Ping {i+1}")
        
        if latencies:
            avg_latency = sum(latencies) / len(latencies)
            min_latency = min(latencies)
            max_latency = max(latencies)
            
            print(f"\nLatenz-Statistik:")
            print(f"  Durchschnitt: {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 ===")
        
        # Testdaten erstellen
        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 += 1
                
                # Kurze Pause um Server nicht zu überlasten
                time.sleep(0.001)
                
            except Exception as e:
                print(f"Fehler beim Senden: {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-Statistik:")
        print(f"  Pakete gesendet: {packets_sent}")
        print(f"  Gesamtdauer: {total_time:.2f}s")
        print(f"  Pakete/Sekunde: {packets_per_second:.2f}")
        print(f"  Durchsatz: {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:
                # Sequenzielle Nummer senden
                packet = f"packet_{i}".encode()
                self.socket.sendto(packet, (self.host, self.port))
                
                # Kurze Pause
                time.sleep(0.001)
                
            except Exception as e:
                packets_lost += 1
        
        loss_rate = (packets_lost / packets) * 100
        print(f"Packet Loss Statistik:")
        print(f"  Pakete gesendet: {packets}")
        print(f"  Pakete verloren: {packets_lost}")
        print(f"  Verlustrate: {loss_rate:.2f}%")
    
    def close(self):
        """Socket schließen"""
        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):
        """Multicast Sender erstellen"""
        sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        
        # TTL setzen (wie viele Hops das Paket machen darf)
        ttl = struct.pack('b', 1)
        sender.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, ttl)
        
        return sender
    
    def create_multicast_receiver(self):
        """Multicast Receiver erstellen"""
        receiver = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        
        # Socket an Multicast-Adresse binden
        receiver.bind(('', self.port))
        
        # Der Multicast-Gruppe beitreten
        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):
        """Multicast-Nachricht senden"""
        sender = self.create_multicast_sender()
        
        try:
            sender.sendto(message.encode(), (self.multicast_group, self.port))
            print(f"Multicast gesendet: {message}")
        finally:
            sender.close()
    
    def receive_multicast(self):
        """Multicast-Nachrichten empfangen"""
        receiver = self.create_multicast_receiver()
        
        try:
            print(f"Multicast Receiver lauscht auf {self.multicast_group}:{self.port}")
            
            while True:
                try:
                    data, address = receiver.recvfrom(1024)
                    print(f"Multicast von {address}: {data.decode()}")
                    
                except KeyboardInterrupt:
                    break
                    
        finally:
            # Gruppe verlassen
            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 für UDP-Demos
def main():
    import sys
    
    if len(sys.argv) > 1:
        mode = sys.argv[1]
        
        if mode == "server":
            # UDP Server starten
            server = UDPServer()
            try:
                server.start()
            except KeyboardInterrupt:
                server.stop()
                
        elif mode == "client":
            # UDP Client starten
            username = input("Ihr 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-Nachricht (oder 'exit'): ")
                if message.lower() == 'exit':
                    break
                multicast.send_multicast(message)
                
        elif mode == "multicast_receive":
            # Multicast Receiver
            multicast = UDPMulticastDemo()
            multicast.receive_multicast()
            
        else:
            print("Verwendung: python udp_demo.py [server|client|performance|multicast_send|multicast_receive]")
    else:
        print("Verwendung: python udp_demo.py [server|client|performance|multicast_send|multicast_receive]")

if __name__ == "__main__":
    main()

3. DNS-запросы на разных языках программирования

Что делает этот код? Эта Java-программа демонстрирует различные операции с DNS: обычное разрешение имён (домен → IP), обратный DNS (IP → домен), получение всех IP-адресов, тестирование производительности DNS и сравнение кеширования DNS (первый и второй запрос).

Зачем это нужно знать? DNS работает как телефонный справочник интернета. Без DNS пришлось бы запоминать IP-адреса. На практике и в собеседованиях нужно уметь диагностировать проблемы с DNS — неверный A-запись, истёкший кеш, недоступный nameserver. Если ты понимаешь DNS, ты поймёшь, почему одни сайты доступны, а другие нет.

Что ты узнаешь?

  • Как InetAddress.getByName() переводит доменные имена в IP-адреса
  • Как работает обратный DNS с той же классом
  • Почему DNS-кеширование важно и как оно влияет на производительность
  • Как программно измерять скорость DNS-запросов
  • Разницу между IPv4 (Inet4Address) и IPv6 (Inet6Address)
import java.net.*;
import java.util.*;

public class DNSLookupDemo {
    
    // Einfache DNS-Abfrage
    public static String dnsLookup(String hostname) {
        try {
            InetAddress address = InetAddress.getByName(hostname);
            return address.getHostAddress();
        } catch (UnknownHostException e) {
            return "Unknown host: " + hostname;
        }
    }
    
    // Reverse DNS-Abfrage (IP → Hostname)
    public static String reverseDNSLookup(String ipAddress) {
        try {
            InetAddress address = InetAddress.getByName(ipAddress);
            return address.getHostName();
        } catch (UnknownHostException e) {
            return "Unknown IP: " + ipAddress;
        }
    }
    
    // Alle IP-Adressen für einen Hostnamen
    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;
    }
    
    // DNS-Record-Typen abfragen (vereinfacht)
    public static void dnsLookupWithTypes(String hostname) {
        System.out.println("=== DNS Lookup für " + 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): Nicht gefunden");
        }
        
        // 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);
    }
    
    // MX-Records abfragen
    public static void dnsLookupMX(String hostname) {
        try {
            // In der Praxis würde man DNS-Bibliotheken wie dnsjava verwenden
            // Hier zeigen wir das Konzept
            System.out.println("MX-Records: Verwendet DNS-Bibliotheken für vollständige Abfrage");
            
            // Beispiel mit einfacher Logik
            if (hostname.endsWith(".com")) {
                System.out.println("  MX: mail." + hostname + " (Beispiel)");
            }
            
        } catch (Exception e) {
            System.out.println("MX-Records: Fehler bei Abfrage - " + e.getMessage());
        }
    }
    
    // NS-Records abfragen
    public static void dnsLookupNS(String hostname) {
        try {
            System.out.println("NS-Records: Verwendet DNS-Bibliotheken für vollständige Abfrage");
            
            // Beispiel mit einfacher Logik
            String[] commonNS = {"ns1." + hostname, "ns2." + hostname};
            for (String ns : commonNS) {
                System.out.println("  NS: " + ns + " (Beispiel)");
            }
            
        } catch (Exception e) {
            System.out.println("NS-Records: Fehler bei Abfrage - " + 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("Durchschnittliche DNS-Lookup Zeit: %.2fms%n", avgTime);
            System.out.printf("Erfolgreiche Lookups: %d/%d%n", successfulLookups, iterations);
        }
    }
    
    // DNS-Caching Demo
    public static void dnsCachingDemo(String hostname) {
        System.out.println("=== DNS Caching Demo ===");
        
        // Erster Lookup (Cache-Miss)
        long start = System.nanoTime();
        String result1 = dnsLookup(hostname);
        long firstLookup = (System.nanoTime() - start) / 1_000_000;
        
        // Zweiter Lookup (Cache-Hit)
        start = System.nanoTime();
        String result2 = dnsLookup(hostname);
        long secondLookup = (System.nanoTime() - start) / 1_000_000;
        
        System.out.println("Erster Lookup: " + firstLookup + "ms");
        System.out.println("Zweiter Lookup: " + secondLookup + "ms");
        
        if (secondLookup < firstLookup) {
            System.out.println("DNS-Caching aktiv (zweiter Lookup schneller)");
        } else {
            System.out.println("Kein DNS-Caching erkannt");
        }
        
        // Ergebnisse vergleichen
        System.out.println("Ergebnis 1: " + result1);
        System.out.println("Ergebnis 2: " + result2);
        System.out.println("Ergebnisse gleich: " + result1.equals(result2));
    }
    
    // IPv6 Support Test
    public static void ipv6SupportTest(String hostname) {
        System.out.println("=== IPv6 Support Test ===");
        
        try {
            // IPv6-Adresse auflösen
            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 ? "Ja" : "Nein"));
            System.out.println("IPv6 Support: " + (hasIPv6 ? "Ja" : "Nein"));
            
        } catch (UnknownHostException e) {
            System.out.println("IPv6 Support Test fehlgeschlagen: " + e.getMessage());
        }
    }
    
    public static void main(String[] args) {
        String hostname = "google.com";
        
        if (args.length > 0) {
            hostname = args[0];
        }
        
        // Verschiedene DNS-Abfragen
        dnsLookupWithTypes(hostname);
        
        // Performance-Test
        dnsPerformanceTest(hostname, 50);
        
        // Caching-Demo
        dnsCachingDemo(hostname);
        
        // IPv6 Support Test
        ipv6SupportTest(hostname);
    }
}

4. HTTP/HTTPS клиент с различными возможностями

Что делает этот код? Программа на Python демонстрирует полнофункциональный HTTP/HTTPS клиент с расширенными возможностями: стратегия повторных попыток, различные HTTP методы (GET, POST, HEAD, OPTIONS), проверка SSL/TLS сертификатов, работа с cookies, отслеживание редиректов, загрузка файлов с индикатором прогресса, тесты производительности и REST API клиент для работы с эндпоинтами.

Почему это важно понимать? HTTP/HTTPS остаётся основным протоколом веб-приложений. Каждый вызов API, каждый запрос страницы, каждая синхронизация данных используют HTTP. Если вы разбираетесь в том, как работают запросы, ответы, коды состояния, заголовки и сессии, вы сможете отлаживать API, выявлять проблемы безопасности и создавать производительные веб-приложения. На экзаменах вопросы про HTTP методы и коды состояния являются стандартными.

Что вы из этого узнаёте?

  • Как создавать переиспользуемые соединения с помощью requests.Session()
  • Почему стратегии повторных попыток важны и как их реализовать с urllib3.util.retry
  • Как читать информацию о SSL сертификатах и версии TLS
  • Как cookies автоматически передаются между запросами
  • Как отслеживать или блокировать редиректы
  • Как эффективно загружать большие файлы с stream=True
  • Как создавать универсальный REST API клиент с CRUD операциями
import requests
import json
import time
import ssl
import urllib3
from urllib3.util.retry import Retry
from datetime import datetime

# HTTP Client с расширенными возможностями
class HTTPClient:
    def __init__(self):
        self.session = requests.Session()
        self.setup_session()
        
    def setup_session(self):
        """Конфигурация сессии"""
        # Стратегия повторных попыток
        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)
        
        # Заголовки
        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 сконфигурирован")
    
    def get_request(self, url, params=None):
        """GET запрос с обработкой ошибок"""
        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 не выполнен: {e}")
            return None
    
    def post_request(self, url, data=None, json_data=None):
        """POST запрос с данными"""
        try:
            print(f"POST Request: {url}")
            
            if json_data:
                print(f"JSON данные: {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 не выполнен: {e}")
            return None
    
    def print_response_info(self, response, duration):
        """Вывод информации об ответе"""
        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')}")
        
        # Вывод заголовков
        if response.headers:
            print("Response Headers:")
            for key, value in response.headers.items():
                print(f"  {key}: {value}")
    
    def test_http_methods(self, url):
        """Тест различных HTTP методов"""
        print(f"=== HTTP Methods Test для {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 не выполнен: {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}")
        except Exception as e:
            print(f"OPTIONS Request не выполнен: {e}")
    
    def test_https_features(self, url):
        """Тест HTTPS возможностей"""
        print(f"=== HTTPS Features Test для {url} ===")
        
        try:
            # Информация о SSL сертификате
            response = self.session.get(url)
            
            # Вывод SSL информации
            cert_info = response.raw._connection.peer.cert
            if cert_info:
                print("Информация о SSL сертификате:")
                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
            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 не выполнен: {e}")
    
    def test_authentication(self, url, username, password):
        """Тест HTTP аутентификации"""
        print(f"=== Authentication Test для {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 выполнена успешно")
            else:
                print("Basic Authentication не выполнена")
                
        except Exception as e:
            print(f"Authentication Test не выполнен: {e}")
    
    def test_cookies(self, url):
        """Тест работы с cookies"""
        print(f"=== Cookie Test для {url} ===")
        
        try:
            # Первый запрос без cookies
            response1 = self.session.get(url)
            print(f"Статус первого запроса: {response1.status_code}")
            print(f"Cookies после первого запроса: {len(self.session.cookies)}")
            
            # Второй запрос с cookies
            response2 = self.session.get(url)
            print(f"Статус второго запроса: {response2.status_code}")
            print(f"Cookies после второго запроса: {len(self.session.cookies)}")
            
            # Информация о cookies
            if self.session.cookies:
                print("Детали cookies:")
                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 не выполнен: {e}")
    
    def test_redirects(self, url):
        """Тест обработки редиректов"""
        print(f"=== Redirect Test для {url} ===")
        
        try:
            # Не следовать редиректам
            response = self.session.get(url, allow_redirects=False)
            print(f"Статус без редиректов: {response.status_code}")
            
            if 300 <= response.status_code < 400:
                location = response.headers.get('Location', 'N/A')
                print(f"Редирект на: {location}")
            
            # Следовать редиректам
            response = self.session.get(url, allow_redirects=True)
            print(f"Статус с редиректами: {response.status_code}")
            print(f"Финальный URL: {response.url}")
            
            # История редиректов
            if hasattr(response.history, '__iter__'):
                print("История редиректов:")
                for i, resp in enumerate(response.history):
                    print(f"  {i+1}. {resp.status_code} -> {resp.url}")
            
        except Exception as e:
            print(f"Redirect Test не выполнен: {e}")
    
    def test_download(self, url, save_path=None):
        """Тест загрузки файла"""
        print(f"=== Download Test для {url} ===")
        
        try:
            response = self.session.get(url, stream=True)
            
            content_length = int(response.headers.get('content-length', 0))
            print(f"Размер файла: {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
                        
                        # Показать прогресс
                        progress = (downloaded / content_length) * 100 if content_length > 0 else 0
                        print(f"\rDownload: {progress:.1f}%", end="", flush=True)
                
                print(f"\nФайл сохранен: {save_path}")
            
        except Exception as e:
            print(f"Download не выполнен: {e}")
    
    def performance_test(self, url, iterations=10):
        """Тест производительности"""
        print(f"=== Performance Test для {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"Запрос {i+1}: {duration:.3f}s")
                
            except Exception as e:
                print(f"Запрос {i+1} не выполнен: {e}")
        
        if times:
            avg_time = sum(times) / len(times)
            min_time = min(times)
            max_time = max(times)
            
            print(f"\nСтатистика производительности:")
            print(f"  Запросов: {len(times)}")
            print(f"  Среднее: {avg_time:.3f}s")
            print(f"  Минимум: {min_time:.3f}s")
            print(f"  Максимум: {max_time:.3f}s")
            print(f"  Запросов в секунду: {1/avg_time:.2f}")

# API клиент для REST API
class APIClient(HTTPClient):
    def __init__(self, base_url):
        super().__init__()
        self.base_url = base_url.rstrip('/')
        
        # API специфичные заголовки
        self.session.headers.update({
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        })
    
    def get_resource(self, resource, params=None):
        """GET ресурс"""
        url = f"{self.base_url}/{resource.lstrip('/')}"
        return self.get_request(url, params)
    
    def create_resource(self, resource, data):
        """POST ресурс"""
        url = f"{self.base_url}/{resource.lstrip('/')}"
        return self.post_request(url, json_data=data)
    
    def update_resource(self, resource, data):
        """PUT ресурс"""
        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 не выполнен: {e}")
            return None
    
    def delete_resource(self, resource):
        """DELETE ресурс"""
        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 не выполнен: {e}")
            return None

# Main для HTTP демонстраций
def main():
    import sys
    
    # HTTP Client Demo
    client = HTTPClient()
    
    # Тест HTTP методов
    client.test_http_methods("https://httpbin.org")
    
    # Тест HTTPS возможностей
    client.test_https_features("https://google.com")
    
    # Тест редиректов
    client.test_redirects("http://httpbin.org/redirect/1")
    
    # Тест cookies
    client.test_cookies("https://httpbin.org/cookies/set/test/value")
    
    # Тест производительности
    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 и стек TCP/IP

Модель OSI (7 слоёв)

СлойНазваниеФункцияПримеры
7ApplicationПротоколы приложенийHTTP, FTP, SMTP
6PresentationПреобразование данныхSSL/TLS, JPEG
5SessionУправление сеансамиNetBIOS, RPC
4TransportСквозная коммуникацияTCP, UDP
3NetworkМаршрутизация и адресацияIP, ICMP
2Data LinkПередача кадровEthernet, WiFi
1PhysicalПередача битовКабели, беспроводные сигналы

Стек TCP/IP (4 слоя)

СлойНазваниеСоответствие OSIПротоколы
4Application5-7HTTP, FTP, DNS
3Transport4TCP, UDP
2Internet3IP, ICMP
1Network Access1-2Ethernet, WiFi

Важные номера портов

Well-Known Ports (0-1023)

ПортПротоколСервис
20FTPПередача файлов (данные)
21FTPПередача файлов (управление)
22SSHЗащищённая оболочка
23TelnetУдалённый терминал
25SMTPЭлектронная почта
53DNSСистема доменных имён
80HTTPВеб (без шифрования)
110POP3Электронная почта (Post Office)
143IMAPЭлектронная почта (Internet Message)
443HTTPSВеб (с шифрованием)
993IMAPSIMAP через SSL
995POP3SPOP3 через SSL

Registered Ports (1024-49151)

ПортПротоколСервис
3306MySQLБаза данных
5432PostgreSQLБаза данных
8080HTTP-AltВеб (альтернативный)
8443HTTPS-AltВеб (альтернативный)
27017MongoDBNoSQL база данных

Сравнение TCP и UDP

ХарактеристикаTCPUDP
СоединениеОриентирован на соединениеБез соединения
НадёжностьГарантированаНе гарантирована
ПорядокГарантированНе гарантирован
Управление потокомДаНет
Обнаружение ошибокДаНет
OverheadВысокийНизкий
СкоростьМедленнееБыстрее
ПрименениеВеб, почтаПотоковая передача, игры

Коды состояния HTTP

1xx Информационные

  • 100 Continue: Продолжение
  • 101 Switching Protocols: Переключение протокола

2xx Успех

  • 200 OK: Успешно
  • 201 Created: Создано
  • 204 No Content: Без содержимого

3xx Перенаправление

  • 301 Moved Permanently: Постоянно перемещено
  • 302 Found: Временно перемещено
  • 304 Not Modified: Не изменено

4xx Ошибка клиента

  • 400 Bad Request: Некорректный запрос
  • 401 Unauthorized: Не авторизовано
  • 403 Forbidden: Запрещено
  • 404 Not Found: Не найдено
  • 429 Too Many Requests: Слишком много запросов

5xx Ошибка сервера

  • 500 Internal Server Error: Внутренняя ошибка сервера
  • 502 Bad Gateway: Ошибка шлюза
  • 503 Service Unavailable: Сервис недоступен

Типы DNS-записей

ТипОписаниеПример
AIPv4-адресexample.com → 93.184.216.34
AAAAIPv6-адресexample.com → 2606:2800:220:1
MXMail Exchangeexample.com → mail.example.com
NSName Serverexample.com → ns1.example.com
CNAMECanonical Namewww.example.com → example.com
TXTТекстовая информацияexample.com → “v=spf1 include:_spf.google.com ~all”
PTRУказатель (обратная запись)93.184.216.34 → example.com

Основы программирования сокетов

Жизненный цикл TCP Socket

// Сервер
1. Создание ServerSocket
2. Ожидание соединения (accept)
3. Создание InputStream/OutputStream
4. Обмен данными
5. Закрытие соединения

// Клиент
1. Создание Socket
2. Подключение к серверу
3. Создание InputStream/OutputStream
4. Обмен данными
5. Закрытие соединения

Жизненный цикл UDP Socket

// Сервер
1. Создание DatagramSocket
2. Ожидание пакетов (receive)
3. Обработка пакета
4. Отправка ответа (send)

// Клиент
1. Создание DatagramSocket
2. Отправка пакета (send)
3. Ожидание ответа (receive)
4. Закрытие сокета

Преимущества и недостатки

Преимущества сетевых протоколов

  • Стандартизация: совместимость между системами
  • Масштабируемость: поддержка больших сетей
  • Надёжность: обработка ошибок и восстановление
  • Гибкость: разные протоколы для разных задач

Недостатки

  • Сложность: много слоёв и протоколов
  • Overhead: дополнительные данные для служебной информации
  • Безопасность: уязвимости для атак
  • Производительность: сетевые задержки

Часто встречающиеся вопросы на экзамене

  1. Что отличает TCP от UDP? TCP ориентирован на соединение и обеспечивает надёжность, а UDP работает без соединения, быстрее, но без гарантий доставки.

  2. Объясните модель OSI! Модель OSI описывает 7 слоёв для сетевой коммуникации от физического уровня до уровня приложений.

  3. Что такое DNS и как он работает? DNS преобразует доменные имена в IP-адреса и наоборот через иерархическую систему серверов имён.

  4. Когда использовать HTTP и когда HTTPS? HTTP применяется для незашифрованной передачи, HTTPS обеспечивает шифрование с помощью SSL/TLS.

Основные источники

  1. https://www.ietf.org/rfc/rfc791.html (TCP)
  2. https://www.ietf.org/rfc/rfc768.html (UDP)
  3. https://www.ietf.org/rfc/rfc1035.html (DNS)
  4. https://www.ietf.org/rfc/rfc2616.html (HTTP/1.1)
Назад к блогу
Share:

Похожие статьи