1. Основы сетевого взаимодействия: модели, адресация, порты и сокеты
Основы сетевого взаимодействия: модели, адресация, порты и сокеты
Эта статья задаёт общий язык для всего курса: что именно происходит, когда ваш backend-сервис принимает запрос, открывает соединение к базе данных или отправляет метрики в UDP. Мы разберём модели сетевого взаимодействия, типы адресации, порты и то, что на практике означает слово сокет в контексте ОС и C#.
Зачем backend-разработчику и сетевому инженеру одинаковые базовые понятия
В сетевом программировании вы постоянно пересекаете границу между:
Если эти уровни смешивать, возникают типичные проблемы: «почему на локалхосте работает, а в Kubernetes нет», «почему иногда теряются UDP-пакеты», «почему порт занят после рестарта».
Модели сетевого взаимодействия: OSI и TCP/IP
Модель OSI
Модель OSI (7 слоёв) удобна как карта, чтобы понимать, на каком уровне находится проблема.
Стек TCP/IP
В реальных ОС и протоколах чаще говорят о TCP/IP (упрощённо 4–5 уровней). Соотнесём модели:
| OSI | TCP/IP (практический стек) | Примеры | |---|---|---| | L1–L2 | Link (канальный) | Ethernet, Wi‑Fi, VLAN | | L3 | Internet | IPv4/IPv6, ICMP | | L4 | Transport | TCP, UDP | | L5–L7 | Application | HTTP, DNS, TLS, SSH |
В этом курсе мы в основном работаем на L4–L7, но постоянно учитываем L2–L3, потому что адресация, маршруты и MTU напрямую влияют на поведение приложений.
Инкапсуляция: что во что «заворачивается»
Данные приложения последовательно оборачиваются заголовками разных уровней. Это важно, потому что на каждом уровне свои адреса и идентификаторы.
!Визуально показывает, что адреса и порты находятся на разных уровнях и идут в разных заголовках
Адресация: MAC, IP, имена (DNS)
MAC-адрес (канальный уровень)
MAC-адрес используется для доставки кадра внутри одного L2-сегмента (обычно одной VLAN/подсети на коммутаторах).
Связка IP→MAC обычно узнаётся через ARP (для IPv4) или NDP (для IPv6).
IP-адрес (сетевой уровень)
IP-адрес нужен для маршрутизации между сетями.
192.0.2.10.2001:db8::10.Ключевые идеи:
Полезные источники:
Имена и DNS (прикладной уровень)
Люди и приложения часто используют имя хоста (например, api.company.local) вместо IP. DNS сопоставляет имя с адресами.
Практически важно:
Источник:
Сводная таблица: что чем адресуется
| Что вы хотите найти | Чем обычно адресуют | Где живёт | |---|---|---| | Соседний узел в одной сети L2 | MAC | Ethernet/Wi‑Fi кадр | | Узел в другой сети | IP | IP пакет | | Конкретный сервис/процесс на узле | Порт + протокол (TCP/UDP) | TCP сегмент / UDP датаграмма | | Удобное человеко-читаемое имя | DNS-имя | DNS/конфигурация |
Порты: как на одном IP живут тысячи сервисов
Порт — это число, которое идентифицирует конечную точку на транспортном уровне (TCP или UDP) внутри хоста.
Важно сразу зафиксировать два факта:
TCP/53 и UDP/53 — разные вещи.Endpoint и 5‑tuple
Соединение (или поток обмена) в сети обычно идентифицируется набором:
Этот набор часто называют 5‑tuple. Он объясняет, почему множество клиентов могут одновременно подключаться к одному dst IP:dst port: у каждого клиента будет уникальная пара src IP:src port.
Диапазоны портов
На практике полезно помнить классику:
Эфемерный (ephemeral) порт — это временный исходящий порт, который ОС выбирает автоматически для клиентского соединения.
TCP и UDP: два базовых транспорта
TCP
TCP даёт:
Цена:
TIME_WAIT).Источник:
UDP
UDP даёт:
Цена:
Источник:
Что такое сокет в ОС и в C#
Сокет — это объект (дескриптор) в операционной системе, через который приложение отправляет и получает данные по сети.
Два взгляда на сокет
Основные операции с сокетами
Для TCP сервера типичный жизненный цикл:
bind к локальному IP:port.listen — перейти в режим ожидания подключений.accept — принять конкретного клиента и получить новый сокет для обмена с ним.Для TCP клиента:
connect к dst IP:dst port;Для UDP:
bind (чтобы принимать на фиксированный порт);Какие классы C# используются на практике
В .NET есть несколько уровней абстракции:
System.Net.Sockets.Socket — низкоуровневый доступ.TcpListener/TcpClient — удобные обёртки для TCP.UdpClient — удобная обёртка для UDP.Документация:
Минимальные примеры на C#: TCP и UDP
Примеры ниже намеренно простые: их цель — связать в голове IP, порт, транспорт и сокет.
TCP: мини-echo сервер
Что важно заметить:
127.0.0.1:5000, то есть доступен только локально.AcceptTcpClientAsync создаёт отдельное TCP-соединение и отдельный объект для клиента.TCP: клиент, который отправляет строку и читает эхо
UDP: приёмник на порту
UDP: отправитель
Что важно заметить:
SendAsync соответствует одной датаграмме.Типовые ошибки, которые важно понять с самого начала
Неправильный bind-адрес
Частые варианты:
127.0.0.1 или ::1: доступно только с локальной машины.0.0.0.0 или ::: слушать на всех интерфейсах (вы становитесь доступнее, но растут требования к firewall и безопасности).Порт занят и TIME_WAIT
Вы можете увидеть «Address already in use» даже после остановки сервиса.
Причины:
TIME_WAIT (нормально для TCP).UDP «не доходит»
Частые причины:
bind-ится на нужный endpoint;DNS даёт «не тот» адрес
Если имя возвращает AAAA-запись, клиент может уйти в IPv6. Если IPv6 маршрутизация или firewall настроены иначе, вы получите неожиданные таймауты.
Как это ляжет на дальнейшие темы курса
Дальше мы будем последовательно углубляться: