9.2. Многоуровневые протоколы¶
Отправка кадра с камеры на сервер в другом городе означает решение нескольких задач одновременно. Электрический сигнал должен пройти по первому проводу. Байты на этом проводе должны найти путь через локальный коммутатор. Локальная сеть должна передать сообщение тому, что находится между ней и остальной частью интернета. Пакеты, пережившие путь, должны быть собраны заново по порядку. Получатель должен знать, какой из своих программ их отдать. А сами байты должны означать нечто, с чем согласны обе стороны.
Попытка решить всё это в одном блоке кода была бы неуправляемой. Стандартный ответ – разделить задачу на уровни. Каждый уровень решает одну чётко определённую задачу и предоставляет простой сервис уровню выше. Программа всегда взаимодействует только с уровнем непосредственно под ней; уровни ниже этого невидимы.
Каждый уровень сетевого стека решает одну задачу и передаёт чистую абстракцию следующему.¶
9.2.1. Пять уровней¶
Приведённые ниже названия – те, которые используются в остальной части этого раздела. Они взяты из стандартной модели, вокруг которой проектировались сети. Точные границы между уровнями иногда размыты, но роль, которую играет каждый из них, стабильна.
Физический уровень. Перемещает биты между двумя устройствами на одном проводе или радиоканале. Уровни напряжения, световые импульсы, RF-модуляция. Задача камеры здесь в основном – подключить правильный кабель или присоединиться к правильной беспроводной сети; остальное делает кремний.
Канальный уровень. Перемещает кадры (небольшие порции байтов) между двумя устройствами, разделяющими локальный сегмент. Добавляет аппаратные адреса, чтобы каждый кадр можно было направить одному конкретному соседу. Ethernet и Wi-Fi – две канальные технологии, с которыми камера сталкивается на практике.
Сетевой уровень. Перемещает пакеты между любыми двумя устройствами в интернете, а не только в одном локальном сегменте. Добавляет адрес программного уровня, который идентифицирует хост независимо от того, к какому кабелю он подключён, и механизм маршрутизации, который передаёт пакет от одного локального сегмента к следующему, пока он не достигнет цели. Это первый уровень, на котором код Python камеры начинает что-то значить.
Транспортный уровень. Располагается поверх пакетов и обеспечивает доставку между программами на двух хостах, а не только между самими хостами. Распространены две разновидности: одна доставляет связный, упорядоченный поток байтов (рабочая лошадка для большей части трафика), другая доставляет самодостаточные сообщения, которые перемещаются независимо друг от друга (используется, когда низкие накладные расходы важнее гарантий). Добавляет номера портов, чтобы несколько программ на одном хосте могли вести разговоры параллельно.
Прикладной уровень. Всё, что выше транспорта: протоколы, которые придают байтам смысл. Те, на которых говорит веб-браузер, чтобы загружать страницы, – и те, что стоят почти за каждым другим интернет-сервисом, которым читатель уже пользуется каждый день, – находятся здесь. Учебник подробно охватывает транспорт; этому уровню посвящён отдельный последующий раздел.
9.2.2. Как уровни складываются во время выполнения¶
Когда камера отправляет байты по сети, каждый уровень добавляет свой собственный заголовок перед данными, словно вкладывая один конверт в другой:
Сначала помещаются байты приложения.
Транспортный уровень оборачивает их небольшим заголовком, указывающим, какой программе они принадлежат (номер порта).
Сетевой уровень оборачивает это заголовком, указывающим, какому хосту они предназначены (адрес программного уровня).
Канальный уровень оборачивает это заголовком, указывающим, какому устройству в локальном сегменте передать их следующим (аппаратный адрес).
Физический уровень превращает весь пакет в биты на проводе.
На другом конце каждый уровень снимает свой собственный заголовок и передаёт остальное наверх. Принимающее приложение получает свои байты обратно, не подозревая, что сетевой, канальный и физический уровни вообще существовали.
Эта вложенность – причина, по которой учебник идёт снизу вверх. Понимание того, что делает уровень снизу, делает уровень сверху неизбежным. Два нижних уровня охвачены по одной странице каждый, потому что из Python почти нечего настраивать. Начиная с сетевого уровня и выше темп замедляется по мере того, как роль Python становится больше.