История изменений (2 обновлений, последнее 30 Aug 2026)
Журнал изменений этой статьи. Там, где версия до правки была заархивирована, она остаётся доступной для чтения по постоянной ссылке с DOI.
- Восстановлено читаемое имя компании: KomuraSoft LLC (合同会社小村ソフト).
- Русский текст переписан как полноценный технический перевод, а не калька с японского. Утверждения статьи не менялись.
- Первая публикация
Цитирование статьи(DOI: 10.5281/zenodo.21619974)
Статья заархивирована на Zenodo. Ниже приведены DOI, который всегда ведёт к последней версии, и DOI, закреплённый за версией, которую вы читаете.
Го Комура (2026). Как ясно представить модель OSI — разбираем один HTTP-запрос по семи уровням. KomuraSoft LLC. https://doi.org/10.5281/zenodo.21619974 https://comcomponent.com/ru/blog/osi-model-packet-anatomy/
- DOI (последняя версия)
- 10.5281/zenodo.21619974
- DOI (эта версия)
- 10.5281/zenodo.21619975
Эталонная модель OSI почти всегда стоит первой главой любого учебника по сетям, и при этом часто слышно одно и то же: «названия семи уровней я перечислю, а вот представить это не получается». Физический, канальный, сетевой… названия выучены, но как эта схема из семи уровней связана с кодом на C#, который вы пишете, или со сбоем связи у вас на глазах, так и остаётся непонятным.
Статья рассчитана на разработчиков Windows-приложений и на тех, кто только начинает разбираться в сетях. В тексте есть фрагменты на C# и команды Windows (ping / tracert / arp и другие), но предварительных знаний о пакетах и протоколах не требуется. Статью можно просто читать, но если хотите проверить всё руками, достаточно среды, где работают .NET SDK (команда dotnet) и Wireshark: тогда содержимое статьи воспроизводится у вас на экране как есть.
В этом блоге мы уже писали о поведении L4 (транспортного уровня) — о заблуждении, будто каждый Send на TCP можно забрать одним соответствующим Receive и о причинах, по которым повторные передачи TCP останавливают связь с промышленной камерой, и как это диагностировать. А вот статьи, которая собрала бы саму идею «уровней», лежащую в основе этого, у нас не было.
Подход простой. Соберём один настоящий Ethernet-кадр с одним HTTP GET и разберём его снаружи внутрь. Семь уровней — не картинка в схеме: они физически вложены друг в друга в тех 171 байте, что идут по сети. Стоит увидеть это своими глазами на hex-дампе и в Wireshark — и модель OSI перестаёт быть предметом зубрёжки.
Код из статьи опубликован на GitHub как готовый к сборке и запуску набор примеров (библиотека сборки и разбора кадров, выгрузка pcap, который открывается в Wireshark, и модульные тесты).
osi-model-packet-anatomy - komurasoft-blog-samples (GitHub)
1. Сначала выводы
- Модель OSI — это словарь, а не реализация. В реальном интернете работает стек протоколов TCP/IP (по сути четыре уровня).1 Собственные протоколы OSI для семи уровней проиграли конкуренцию и почти не применялись.2 Выжила модель как общий язык: «разберёмся на L2», «это проблема L7».
- Семь уровней физически вложены друг в друга как последовательность байт. В кадре с HTTP GET первые 14 байт — заголовок Ethernet (L2), следующие 20 — заголовок IPv4 (L3), ещё 20 — заголовок TCP (L4), остальное — текст HTTP (L7). Что заголовок каждого уровня начинается сразу после предыдущего, видно на hex-дампе в статье и в Wireshark.
- Код на C# напрямую пишет только байты L7. В
Socket.Sendпередаются только данные приложения; заголовки TCP и IP добавляет стек протоколов ОС, заголовок Ethernet и электрический сигнал — сетевой адаптер (NIC). Поэтому выбор междуHttpClient,SslStreamиSocket— это выбор, с какого уровня и ниже работу отдаёте ОС.3 - L5 (сеансовый) и L6 (представления) как отдельные уровни в реальном стеке не существуют. Часть их роли берут TLS и кодировка символов, но в модели TCP/IP всё это — прикладной уровень. Если «не понимаю, что такое L6» — про вас, это не ваша вина: здесь модель и реальность расходятся.1
- На практике модель OSI нужна при диагностике и в разговоре. Сужение поиска языком уровней — «ping проходит, HTTP нет, значит до L3 всё живо, смотрим L4 и выше» — становится общим языком сетевых инженеров, инфраструктурных команд и разработчиков приложений.
Карта знаний этой статьи
Эталонная модель OSI задумывалась как стандарт вместе с протоколами OSI для каждого из семи уровней, но в конкуренции за внедрение победил стек TCP/IP, и реальный интернет работает по сути на четырёх уровнях: канальном, IP, транспортном и прикладном. Ethernet-кадр с HTTP-запросом имеет вложенную структуру (инкапсуляцию): Ethernet (L2, доставка по MAC-адресу), IPv4 (L3, IP назначения не меняется при проходе через маршрутизаторы), TCP (L4, разбор по номеру порта и надёжный байтовый поток) и HTTP (L7); это видно по соответствию панели сведений о пакете и панели байтов в Wireshark. Socket в .NET передаёт только байты L7, заголовки TCP/IP добавляет ОС; SslStream оборачивает TCP-поток в TLS; HttpClient берёт на себя и сборку L7. На практике модель OSI нужна, чтобы пошагово проверять уровни снизу вверх при диагностике и как общий язык между командами.
flowchart LR
accTitle: Карта знаний: эталонная модель OSI и структура пакета TCP/IP
accDescr: Ethernet-кадр с HTTP-запросом вложен как Ethernet, IPv4, TCP и HTTP (инкапсуляция); модель OSI — не реализация, а словарь для диагностики; Socket, SslStream и HttpClient в .NET закрывают разные уровни.
osi_model["эталонная модель OSI"]
tcp_ip_protocol_suite["стек протоколов TCP/IP"]
osi_protocol_suite["протоколы OSI"]
ethernet["Ethernet (L2)"]
mac_address["MAC-адрес"]
arp["ARP"]
ipv4["IPv4 (L3)"]
ttl["TTL (Time To Live)"]
tracert["tracert"]
tcp["TCP (L4)"]
port_number["номер порта"]
http["HTTP"]
tls["TLS"]
dotnet_sslstream["SslStream (.NET)"]
dotnet_socket["Socket (.NET)"]
dotnet_httpclient["HttpClient (.NET)"]
encapsulation["инкапсуляция (полезная нагрузка уровней)"]
wireshark["Wireshark"]
network_layer_troubleshooting["диагностика по уровням"]
tcp_ip_protocol_suite -->|"преемник"| osi_protocol_suite
ethernet -->|"использует"| mac_address
ethernet -.->|"требует"| arp
ipv4 -->|"использует"| ttl
tracert -->|"использует"| ttl
tcp -->|"использует"| port_number
tcp -.->|"требует"| ipv4
ipv4 -.->|"использует"| ethernet
http -.->|"использует"| tcp
tls -->|"использует"| tcp
dotnet_sslstream -->|"реализует"| tls
dotnet_socket -.->|"использует"| tcp
dotnet_httpclient -->|"реализует"| http
tcp_ip_protocol_suite -->|"использует"| encapsulation
encapsulation -->|"проверяется"| wireshark
mac_address -->|"проверяется"| arp
osi_model -->|"рекомендуется для"| network_layer_troubleshooting
network_layer_troubleshooting -->|"использует"| tcp
network_layer_troubleshooting -->|"использует"| ipv4
network_layer_troubleshooting -->|"использует"| http
На схеме сплошная линия обозначает отношение, которое выполняется всегда, а пунктирная — условное отношение (условия указаны в пояснении к каждому отношению на странице сведений). Полный список отношений (всего 20, с доказательствами и степенью уверенности) и определения основных понятий собраны на странице сведений карты знаний (на японском). Данные: JSON-LD / Turtle
2. Почему модель OSI так и остаётся зубрёжкой
Большинство объяснений начинаются с такой таблицы.
| Уровень | Название | Описание |
|---|---|---|
| L7 | Прикладной уровень | Предоставляет приложениям сервисы связи |
| L6 | Уровень представления | Преобразует формат представления данных |
| L5 | Сеансовый уровень | Управляет началом и завершением сеанса связи |
| L4 | Транспортный уровень | Обеспечивает надёжную передачу данных |
| L3 | Сетевой уровень | Выполняет выбор маршрута и адресацию |
| L2 | Канальный уровень | Передаёт данные между соседними узлами |
| L1 | Физический уровень | Преобразует биты в электрические сигналы |
Таблица верная, но каждая строка написана настолько абстрактно, что при чтении не складывается никакой картины. Скажите «преобразует формат представления данных» — и вряд ли кто-то укажет, о какой именно строке своего кода речь.
Стоит прямо назвать ещё один исторический факт. Модель OSI — стандарт ISO (Международная организация по стандартизации) и ITU-T (ISO/IEC 7498-1, ITU-T X.200). Изначально это была масштабная задумка: семь уровней плюс набор протоколов OSI под каждый из них.2 Но в конкуренции за внедрение в 1990-х фактическим стандартом стал TCP/IP — у него уже были работающие реализации, а сами протоколы OSI так и остались почти невостребованными. RFC 1122, заложивший основы интернета, описывает мир по сути четырьмя уровнями — канальным, уровнем интернета (IP), транспортным и прикладным, — без отдельных уровней, соответствующих L5 и L6.1
Иначе говоря, сегодня модель OSI изучают не потому, что «система устроена именно так», а чтобы получить инструмент мышления уровнями и общий словарь для диагностики. Если принять эту предпосылку, вопрос «где же настоящие L5 и L6» отпадает, и картина сразу становится яснее.
3. Главное: разбираем один HTTP-запрос
На этом со вступлением закончим и посмотрим на реальный объект. Следующий hex-дамп — Ethernet-кадр (всего 171 байт) с одним HTTP-запросом GET /index.html HTTP/1.1. Его собрал пример кода из начала статьи; контрольные суммы заголовка IPv4 и TCP посчитаны правильно, поэтому Wireshark показывает кадр как нормальный пакет.
0000 02 00 00 00 00 01 02 00 00 00 00 02 08 00 45 00 ..............E.
0010 00 9d 12 34 40 00 40 06 3b 99 c0 00 02 0a c6 33 ...4@.@.;......3
0020 64 50 cb 84 00 50 00 00 03 e8 00 00 07 d0 50 18 dP...P........P.
0030 ff ff a3 05 00 00 47 45 54 20 2f 69 6e 64 65 78 ......GET /index
0040 2e 68 74 6d 6c 20 48 54 54 50 2f 31 2e 31 0d 0a .html HTTP/1.1..
0050 48 6f 73 74 3a 20 65 78 61 6d 70 6c 65 2e 63 6f Host: example.co
0060 6d 0d 0a 55 73 65 72 2d 41 67 65 6e 74 3a 20 4b m..User-Agent: K
0070 6f 6d 75 72 61 53 6f 66 74 44 65 6d 6f 2f 31 2e omuraSoftDemo/1.
0080 30 0d 0a 41 63 63 65 70 74 3a 20 74 65 78 74 2f 0..Accept: text/
0090 68 74 6d 6c 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e html..Connection
00a0 3a 20 63 6c 6f 73 65 0d 0a 0d 0a : close....
В столбце ASCII справа видно, что где-то посередине (со смещения 0x36) начинается читаемый человеком текст GET /index.html HTTP/1.1. Что тогда за 54 байта перед ним? Если прогнать кадр через разборщик из примера, он выдаст такой отчёт.
[ L2 Ethernet II | offset 0 | 14 bytes | dst=02:00:00:00:00:01 src=02:00:00:00:00:02 type=0x0800 (IPv4)
[ L3 IPv4 | offset 14 | 20 bytes | 192.0.2.10 -> 198.51.100.80 TTL=64 proto=6 (TCP) checksum=OK
[ L4 TCP | offset 34 | 20 bytes | 52100 -> 80 [Psh, Ack] seq=1000 win=65535
[ L7 HTTP | offset 54 | 117 bytes | GET /index.html HTTP/1.1
Это схема, на которую в статье стоит смотреть в первую очередь. В ней три пункта.
- Каждый уровень начинается сразу после предыдущего. Заголовок Ethernet — байты 0–13, IPv4 — 14–33, TCP — 34–53, HTTP начинается с 54-го байта. Уровень — не абстрактная категория, а диапазон байт от начала кадра, на который можно указать пальцем.
- Внутренний уровень — это полезная нагрузка (payload) внешнего. Для Ethernet всё после него, начиная с IPv4, — просто полезная нагрузка; TCP там внутри или нет, Ethernet не интересует. Для IP нагрузка — всё после него (TCP), для TCP нагрузка — HTTP. Каждый уровень читает только свой заголовок и передаёт нагрузку выше, не трогая её. Именно эта структура «внутрь не заглядываю» и есть инкапсуляция.
- L1 (физический уровень) и L5/L6 на этой схеме нет. Работа L1 — превратить эту последовательность байт в электрический сигнал, свет или радиоволны, поэтому в дампе её не видно. L5 и L6, как уже сказано в предыдущей главе, в открытом HTTP/1.1 не имеют отдельной сущности. «Из семи уровней в дампе видны четыре» — такова реальность.
Повторим: дело не в особенности HTTP. Соединение с базой, gRPC, GigE Vision промышленной камеры — любой пакет TCP/IP поверх Ethernet имеет ту же вложенную структуру. Меняется только содержимое полезной нагрузки L7.
4. L2, канальный уровень — доставка до соседа
Пройдём разбор снаружи внутрь. Первые 14 байт — заголовок Ethernet II.
02 00 00 00 00 01 MAC-адрес назначения (6 байт)
02 00 00 00 00 02 MAC-адрес источника (6 байт)
08 00 EtherType = 0x0800 (нагрузка — IPv4)
Задача L2 — доставить кадр до соседнего узла в том же сетевом сегменте. Получателя задают MAC-адресом. MAC — идентификатор, назначенный сетевому адаптеру; как правило, через маршрутизатор до конечного получателя он не доходит. У кадра с офисного ПК на веб-сервер MAC назначения — не веб-сервер, а шлюз по умолчанию (маршрутизатор).
Здесь у многих хотя бы раз возникает вопрос: «если уже есть IP, зачем ещё MAC?». Ответ — в разделении ролей между уровнями. IP-адрес указывает конечный пункт назначения, MAC — кому отдать кадр на следующем участке. Как в доставке: IP — адрес получателя на накладной, MAC — название следующего сортировочного центра. Накладная (L3) не меняется до конца пути, а «кому отдать на этом участке» (L2) меняется на каждом хопе. MAC соседнего узла по IP находит ARP; таблицу, которую помнит ПК, смотрят командой arp -a.
Из оборудования кадры по L2 пересылает коммутатор (switching hub). Коммутатор выбирает порт только по MAC назначения и в IP внутри полезной нагрузки не заглядывает.
5. L3, сетевой уровень — доставка до конечного хоста
Следующие 20 байт — заголовок IPv4. Выделим основные поля.
45 Версия=4, длина заголовка=5 слов (20 байт)
00 9d Полная длина 157 байт (заголовок IP + TCP + HTTP; 14 байт Ethernet не входят)
40 06 TTL=64, протокол=6 (нагрузка — TCP)
3b 99 Контрольная сумма заголовка
c0 00 02 0a IP источника 192.0.2.10
c6 33 64 50 IP назначения 198.51.100.80
Задача L3 — доставить пакет до конечного хоста, сколько бы маршрутизаторов ни было на пути. L2 несёт кадр только на один участок (один хоп), а IP назначения на L3 не меняется от начала до конца передачи. Маршрутизатор смотрит IP назначения полученного пакета, решает, какому маршрутизатору отдать его дальше, перезаписывает заголовок L2 и отправляет дальше.
Это движение «меняется только L2» выглядит так. На каждом участке меняются MAC назначения и источника (L2); IP назначения (L3) на всех трёх участках один и тот же.
flowchart LR
PC["ПК-отправитель<br/>192.0.2.10"]
R1["Маршрутизатор 1"]
R2["Маршрутизатор 2"]
SV["Веб-сервер<br/>198.51.100.80"]
PC -->|"MAC назначения: маршрутизатор 1<br/>IP назначения: 198.51.100.80"| R1
R1 -->|"MAC назначения: маршрутизатор 2<br/>IP назначения: 198.51.100.80"| R2
R2 -->|"MAC назначения: веб-сервер<br/>IP назначения: 198.51.100.80"| SV
Рис. 1: На каждом участке меняются только MAC-адреса (L2), IP назначения (L3) остаётся прежним до конца. TTL уменьшается на 1 при каждом проходе через маршрутизатор.
TTL (Time To Live) как раз делает это «проход через маршрутизатор» видимым. Поле уменьшается на 1 на каждом маршрутизаторе; когда доходит до 0, пакет отбрасывается, отправителю возвращается ошибка. tracert (команда Windows для трассировки маршрута) нарочно шлёт пакеты с TTL 1, 2, 3… и тем самым выявляет промежуточные маршрутизаторы по одному. Каждая строка в выводе tracert — это и есть хоп уровня L3.
6. L4, транспортный уровень — какому процессу отдать
Следующие 20 байт — заголовок TCP.
cb 84 Порт источника 52100
00 50 Порт назначения 80
00 00 03 e8 Порядковый номер
00 00 07 d0 Номер подтверждения
50 18 Длина заголовка=5 слов, флаги [PSH, ACK]
ff ff Размер окна
a3 05 Контрольная сумма
К концу работы L3 пакет уже на хосте (машине) назначения. Но на этой машине одновременно могут работать веб-сервер, база и ещё много процессов, которые тоже обмениваются данными. Одна из задач L4 — по номеру порта решить, какому процессу (какому сокету) отдать данные. Порт назначения 80 по соглашению — номер, на котором слушает HTTP-сервер; ОС смотрит на этот номер и кладёт данные в буфер приёма соответствующего процесса.
Другая большая задача TCP — надёжный байтовый поток за счёт порядковых номеров, подтверждений, повторных передач и управления потоком.4 Само это поведение и то, как с ним жить, тянет на отдельные статьи, поэтому подробности — в материале о границах сообщений в TCP и в материале о повторных передачах TCP. Здесь достаточно поймать ощущение: «начиная с L4 и выше это уже не сеть, а труба между процессами».
Есть любопытный факт, который показывает, где идеал модели расходится с реальностью. Контрольная сумма TCP считается не по одному сегменту TCP, а с псевдозаголовком впереди, в который входят данные L3 (IP источника и назначения).4 Если бы уровни были строго независимы, адреса L3 не должны были бы попадать в расчёт L4. Это хороший пример: модель OSI — карта для упорядочивания мысли, а реальные протоколы при необходимости пересекают границы уровней.
7. L5 и L6 — где модель расходится с реальностью
На схеме разбора не было ни L5 (сеансового уровня), ни L6 (уровня представления). Это главная причина, почему OSI «не складывается», поэтому скажем прямо.
L5 и L6 как отдельные уровни в реальном стеке TCP/IP не существуют. В модели интернета по RFC 1122 всё выше TCP — просто «прикладной уровень».1 Роли, которые закладывала модель OSI, на практике разошлись и поглощены так:
| Задумка OSI | Куда это ушло на практике |
|---|---|
| L5: установление и ведение диалога (сеанса) | TLS-сеанс и handshake, cookie и токены HTTP, собственная логика входа в приложении |
| L6: преобразование представления и шифрование | Шифрование TLS, кодировка символов (UTF-8), форматы сериализации вроде JSON |
Например, в HTTPS поверх TCP (L4) встаёт TLS, а HTTP идёт уже внутри него. Вопрос «TLS — это какой уровень?» так и просится в экзаменационный билет, но закреплять за ним один правильный ответ на практике бессмысленно. Важнее не мгновенно сказать «это L6», а уметь объяснить: выше L4, ниже L7, совмещает ведение сеанса (роль в духе L5) и шифрование (роль в духе L6).
В коде .NET это же отношение видно в том, как классы оборачивают друг друга. Если поток L4 из TcpClient.GetStream() обернуть в SslStream, то открытый текст, записанный через Write, сначала шифруется в TLS-запись и только потом уходит в TCP.5
using var client = new TcpClient("example.com", 443);
// Байтовый поток L4 оборачиваем в TLS (роли, близкие к L5/L6)
using var ssl = new SslStream(client.GetStream());
await ssl.AuthenticateAsClientAsync("example.com");
// Сюда пишется открытый текст L7 (HTTP). Шифрование — работа SslStream
await ssl.WriteAsync(Encoding.ASCII.GetBytes("GET / HTTP/1.1\r\n..."));
Поток, обёрнутый в поток, — это инкапсуляция в коде. Если в Wireshark смотреть трафик порта 443, полезная нагрузка TCP видна только как непрозрачный блок Application Data: с другой стороны видно, что L7 оказался внутри обёртки, близкой к L6.
8. Какой уровень на самом деле трогает ваш код на C#
Сопоставим сказанное с инструментами разработчика Windows-приложений.
| Уровень | Пример из практики | Пример API .NET | Кто добавляет заголовок |
|---|---|---|---|
| L7 прикладной | HTTP, gRPC, свой протокол | HttpClient, Grpc.Net.Client, самостоятельная сборка сообщений |
Ваш код / библиотека |
| (роли L5/L6) | TLS, сериализация, кодировка | SslStream, JsonSerializer, Encoding |
Библиотека |
| L4 транспортный | TCP, UDP | Socket, TcpClient, UdpClient (заголовок формирует ОС) |
Стек протоколов ОС |
| L3 сетевой | IP, маршрутизация, ICMP | Ping, NetworkInterface (только чтение) |
Стек протоколов ОС |
| L2 канальный | Ethernet, Wi-Fi, ARP | (из обычного приложения напрямую не трогают) | Драйвер NIC / сам NIC |
| L1 физический | Электрический сигнал, свет, радиоволны | ── | NIC / кабель / среда |
Из таблицы следуют два вывода.
Первое: выбор API — это выбор, с какого уровня и ниже работу отдаёте. С HttpClient можно отдать и сборку L7; с Socket весь L7 пишете сами. И наоборот, обычное Windows-приложение почти никогда не работает напрямую с L3 и ниже (raw-сокеты требуют прав администратора и жёстко ограничены).
Второе: в Socket.Send передаются только байты L7. Часть 2 примера шлёт настоящий HTTP-запрос через loopback: приложение готовит только 60 байт HTTP-текста; те 54 байта заголовков из главы 3 добавляют ОС и NIC. Сетевой код вашего приложения на самом деле собирает только самую внутреннюю полезную нагрузку из семи уровней — такова точная позиция модели OSI относительно вашего кода.
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
await socket.ConnectAsync(IPAddress.Loopback, port);
byte[] request = Encoding.ASCII.GetBytes(
$"GET / HTTP/1.1\r\nHost: localhost:{port}\r\nConnection: close\r\n\r\n");
// Передаются только байты L7. Заголовки TCP/IP/Ethernet
// добавляются по ту сторону этого вызова (ОС и NIC)
int sent = await socket.SendAsync(request);
9. Практика: собираем кадр и открываем его в Wireshark
Чтобы из «прочитал и понял» сделать «увидел и понял», расскажем, как запустить пример.
Центр примера — SampleFrameBuilder, который собирает кадр из главы 3 в том же порядке, в каком он оборачивается от L7 к L2. Порядок методов — это то, что происходит на каждом уровне при отправке.
public static byte[] BuildHttpGetFrame()
{
// L7: приложение передаёт в Send только эту последовательность байт
byte[] http = Encoding.ASCII.GetBytes(HttpRequest);
// L4: стек протоколов ОС ставит заголовок TCP впереди
byte[] tcp = WrapInTcp(http);
// L3: затем впереди ставится заголовок IPv4
byte[] ip = WrapInIpv4(tcp);
// L2: перед драйвером NIC впереди ставится заголовок Ethernet
return WrapInEthernet(ip);
}
При запуске демо кроме hex-дампа и вложенного представления этот кадр записывается как pcap-файл.
dotnet run --project samples/Demo
Откройте получившийся sample-http-get.pcap в Wireshark.6 В центральной панели (панель сведений о пакете) друг под другом встанут четыре строки — Ethernet II / Internet Protocol Version 4 / Transmission Control Protocol / Hypertext Transfer Protocol. Щелчок по любой из них подсвечивает только соответствующий диапазон байт в нижней панели (панель байтов). Это соответствие выглядит так: то же вложенное представление, что в главе 3, показывает отраслевой стандартный инструмент.
flowchart LR
subgraph DETAIL["Панель сведений о пакете — четыре строки сверху вниз"]
E["Ethernet II"]
I["Internet Protocol Version 4"]
T["Transmission Control Protocol"]
H["Hypertext Transfer Protocol"]
end
subgraph BYTES["Панель байтов — подсвечиваемый диапазон"]
BE["байты 0–13"]
BI["байты 14–33"]
BT["байты 34–53"]
BH["байты 54–170"]
end
E -->|"клик"| BE
I -->|"клик"| BI
T -->|"клик"| BT
H -->|"клик"| BH
Рис. 2: Соответствие строк панели сведений и диапазонов в панели байтов. Если выбрать строку, внизу подсвечивается только диапазон заголовка этого уровня.
Когда это видно, переходите к реальному трафику. Запустите захват в Wireshark, поставьте фильтр вроде tcp.port == 443, откройте в браузере какой-нибудь сайт — и убедитесь, что весь настоящий обмен собран из той же вложенности.
В реализацию разборщика (PacketDissector) тоже заложен практический урок. Например, вырезая полезную нагрузку IPv4, нельзя брать весь остаток буфера приёма: нужно доверять полю TotalLength в заголовке и резать строго по нему. У Ethernet есть минимальная длина кадра (60 байт), и к коротким пакетам в конец дописывается бессмысленный padding. «Особенность внешнего уровня (padding) убирают по информации о длине из внутреннего» — ещё один случай, когда разделение ролей между уровнями видно в коде; это проверяется модульным тестом.
10. Модель OSI на практике — диагностика языком уровней
В начале статьи сказано: OSI выжила как словарь. Вот два места, где этот словарь реально помогает.
Диагностика сбоев. Жалобу «не подключается к серверу» можно системно сужать, переведя её на язык уровней. Правило — проверять снизу вверх.
| Проверка | Чем пользоваться | Какой уровень подтверждается как живой |
|---|---|---|
| Индикатор линка / индикатор Wi-Fi | Визуально | L1–L2 |
| Ping шлюза в том же сегменте | ping 192.168.x.1 |
L3 рядом с собой |
| Ping удалённого хоста | ping <адрес> |
L3 на всём маршруте |
| TCP-подключение к порту получателя | Test-NetConnection <адрес> -Port 443 |
L4 (плюс межсетевые экраны по пути) |
| Отправка HTTP-запроса | curl -v или само приложение |
L7 (плюс TLS) |
Например, если ping проходит, а Test-NetConnection не срабатывает, до L3 всё в порядке, и подозрение сужается до того, что блокирует порт на L4 (служба не запущена, межсетевой экран, ошибка в номере порта). Если TCP-соединение есть, а HTTP отвечает 400, сеть ни при чём: это L7 (содержимое запроса). Вместо того чтобы наугад дёргать кабели, по шагам фиксируют, до какого уровня всё живо — так модель OSI применяют на практике.
Общий язык. Фразы вроде «похоже на L2, посмотрите порт коммутатора» или «это L7, значит к команде приложения» точно понимают и сетевые инженеры, и инфраструктура, и разработчики. Номер уровня — общая для отрасли система координат, чтобы коротко назвать границу ответственности.
11. Частые заблуждения
В конце разберём типичные ошибки вокруг модели OSI.
- «Интернет работает на семи уровнях OSI» — нет. Реализован TCP/IP (по сути четыре уровня), OSI — справочная модель для объяснения и разговора.1
- «Четыре уровня TCP/IP точно соответствуют семи уровням OSI» — соответствие L5–L7 по сути размыто. Часто рисуют таблицу «прикладной уровень TCP/IP = L5 + L6 + L7 модели OSI», но, как в главе 7, роли L5 и L6 на практике разошлись между TLS и форматами сериализации.
- «TLS — протокол шестого (или пятого) уровня» — закреплять его за одним уровнем бессмысленно. Точнее: выше L4, ниже L7, совмещает роли, близкие к L5 и L6.
- «По номеру порта видно протокол» — порт 80 не гарантирует HTTP. Номер порта — соглашение; что там на самом деле идёт, не узнать, пока не посмотреть полезную нагрузку. Поэтому разборщик из примера определяет HTTP не по порту, а по начальным символам содержимого.
- «Коммутатор — устройство L2, маршрутизатор — устройство L3» — как отправная точка это верно, но на практике обычны устройства сразу на нескольких уровнях: L3-коммутаторы, балансировщики, которые разбирают L4, WAF, которые смотрят L7. Точнее спрашивать, до какого уровня устройство читает кадр.
12. Кратко
- Модель OSI — не реализация, а словарь для мышления уровнями. В реальности работает TCP/IP (по сути четыре уровня)
- Семь уровней — не схема на бумаге, а физическая вложенность внутри байт одного кадра (L2: 0–13, L3: 14–33, L4: 34–53, L7: с 54-го)
- Каждый уровень читает только свой заголовок и не заглядывает в полезную нагрузку (внутренние уровни) — это инкапсуляция
- L5 и L6 в реальном стеке отдельно не существуют; их роли поглотили TLS и кодировки
- Код на C# пишет только байты L7. Заголовки TCP/IP добавляет ОС, Ethernet — NIC
- На практике это диагностика снизу вверх и общий язык между командами
- Собрав кадр примером и открыв его в Wireshark, всё из статьи можно проверить своими глазами
Похожие статьи
- Заблуждение, будто каждый Send на TCP можно забрать одним Receive — как проектировать приём как байтовый поток
- Почему повторные передачи TCP останавливают связь с промышленной камерой и как это диагностировать
- Практическая таблица решений по C# async/await — Task.Run и ConfigureAwait
Смежные направления консультирования
KomuraSoft LLC (合同会社小村ソフト) занимается проектированием и реализацией Windows-приложений с обменом по TCP/IP, поиском причин сбоев связи с промышленным оборудованием («иногда обрывается», «тормозит») и помощью в диагностике по захвату пакетов.
- Разработка Windows-приложений
- Расследование сбоев и анализ причин
- Технический консалтинг и ревью проектных решений
- Контакты
Справочные ссылки
-
IETF, RFC 1122 - Requirements for Internet Hosts – Communication Layers. RFC с требованиями к интернет-хостам. О том, что стек протоколов описан четырьмя уровнями: канальным, IP, транспортным и прикладным. ↩ ↩2 ↩3 ↩4 ↩5
-
ITU-T, X.200 : Information technology - Open Systems Interconnection - Basic Reference Model: The basic model. Первоисточник базовой эталонной модели OSI (по содержанию совпадает с ISO/IEC 7498-1). Об определении каждого из семи уровней. ↩ ↩2
-
Microsoft Learn, Socket Class (System.Net.Sockets). API сокетов в .NET. О том, что приложение передаёт полезную нагрузку, а заголовки протоколов формирует стек протоколов ОС. ↩
-
IETF, RFC 9293 - Transmission Control Protocol (TCP). Действующая спецификация TCP. О надёжности за счёт порядковых номеров и подтверждений и о псевдозаголовке с IP-адресами при расчёте контрольной суммы. ↩ ↩2
-
Microsoft Learn, SslStream Class (System.Net.Security). О классе, который оборачивает существующий поток (обычно TCP
NetworkStream) и даёт шифрование и аутентификацию по TLS. ↩ -
Wireshark Foundation, Wireshark User’s Guide. Об открытии файлов захвата, соответствии панели сведений о пакете и панели байтов и об использовании фильтров отображения. ↩
Похожие статьи
Недавние статьи с теми же тегами помогут подробнее изучить близкие темы.
TCP не отдаёт Receive теми же порциями, что Send — приём как байтовый поток
Если считать, что в TCP данные приходят теми же порциями, которыми их отправили через Send или Write, возникают разбиение, склейка, порча...
Захват пакетов в Windows на практике — pktmon, netsh trace и Wireshark
Сбой связи, в журнале приложения которого остаётся только «timeout», разбирают по пакетам, которые реально прошли по проводу. Даже на сер...
Практические рекомендации по многопоточности: .NET — что решить до добавления потоков
Проверенные приёмы проектирования на .NET/C#, чтобы код не «иногда падал или зависал»: не создавать потоки вручную и опираться на Task, с...
WMI/CIM из C# и PowerShell — практическое руководство по сведениям об оборудовании, мониторингу процессов и удалённым запросам
WMI/CIM — стандартный способ получить серийный номер ПК, следить за свободным местом на диске и ловить запуск процессов. Разбираем команд...
Глубины ввода-вывода Windows (часть 4) — диспетчер кэша: когда WriteFile оказывается на диске
Четвёртая часть серии со схемами диспетчера кэша Windows. Разбираем кэш как проекцию файла, упреждающее чтение и отложенную запись, когда...
Связанные темы
Эти страницы показывают тему статьи в более широком контексте услуг и решений.
Технические темы Windows
Раздел о разработке Windows, расследовании сбоев и использовании существующих активов.
Расследование ошибок и долгие сбои
Периодические сбои, диагностика связи, сбои после длительной работы и проверка путей отказа.
Услуги по этой теме
Статья напрямую связана со следующими услугами.
Разработка приложений для Windows
Бизнес-приложения, интеграция оборудования и средства связи — от требований до разработки.
Частые вопросы
Вопросы, которые часто возникают при консультациях по теме статьи.
- Семь уровней модели OSI реально используются в интернете?
- Нет. В реальном интернете работает стек протоколов TCP/IP (по сути четыре уровня). Собственные протоколы OSI для семи уровней проиграли конкуренцию в 1990-х и почти не применялись. RFC 1122, заложивший основы интернета, описывает мир четырьмя уровнями: канальным, уровнем IP, транспортным и прикладным. Выжила модель как общий словарь для диагностики и разговора: «разберёмся на L2», «это проблема L7».
- Где на практике сеансовый уровень (L5) и уровень представления (L6)?
- Как отдельные уровни в реальном стеке TCP/IP их нет. Роли, которые закладывала модель OSI, на практике разошлись по другим местам: L5 (установление и ведение сеанса) — это TLS-handshake, cookie и токены HTTP; L6 (преобразование представления и шифрование) — шифрование TLS, кодировка символов и форматы сериализации вроде JSON. Закреплять TLS за одним уровнем на практике бессмысленно: важнее уметь объяснить, что он сидит выше L4 и ниже L7 и совмещает роли, близкие к L5 и L6.
- Если уже есть IP-адрес, зачем ещё MAC-адрес?
- Уровни решают разные задачи. IP-адрес (L3) указывает конечный пункт назначения и не меняется от начала до конца передачи. MAC-адрес (L2) указывает, кому отдать кадр на следующем участке, и меняется при каждом проходе через маршрутизатор. У кадра с офисного ПК на веб-сервер MAC назначения — не веб-сервер, а шлюз по умолчанию (маршрутизатор). MAC соседнего узла по IP находит ARP; таблицу соответствия смотрят командой arp -a.
- Какая практическая польза от модели OSI?
- Диагностика сбоев и общий язык между командами. Жалобу «не подключается к серверу» можно сужать системно, проверяя уровни снизу вверх: индикатор линка (L1–L2), ping шлюза (L3), TCP-подключение к порту получателя (L4), отправка HTTP-запроса (L7). Если ping проходит, а TCP-соединение не устанавливается, подозрение сужается до того, что блокирует порт на L4 — остановленная служба или межсетевой экран. Модель также даёт общую систему координат, чтобы коротко назвать границу ответственности: «похоже на L2, посмотрите коммутатор».
Об авторе
Страница с профилем автора статьи.
Го Комура
Представитель KomuraSoft LLC
Специализируется на разработке программного обеспечения для Windows, техническом консалтинге и расследовании сбоев, особенно в проектах с унаследованными системами и трудно воспроизводимыми ошибками.