---
# System prepended metadata

title: '**Транспортный уровень протоколов**'
tags: [сети]

---

---
tags: сети
---
# **Транспортный уровень протоколов**

## Описание:
Задачи транспортного уровня:
* Передача данных между процессами на хостах
* Адресация
* Предоставление нужного уровня надежности передачи данных, вне зависимости от надежности сети

Транспортный уровень характерен только для конечных пользователей сети (ПК, сервер). Для сетевого оборудования (роутеры, свитчи) он не так важен.
![](https://i.imgur.com/Lw3e6ui.png)

Транспортный уровень обеспечивает так называемое "сквозное" соединение, не зависящее от количества устройств, через которые пройдут данные по пути к точке назначения. Поэтому транспортный уровень называется сетенезависимым.

Для адресации на транспортном уровне используются порты (число от 1 до 65535). Каждое сетевое приложение на хосте имеет свой порт. 

Есть три типа портов:

![](https://i.imgur.com/5sk9etr.png)

1) Хорошо изестные - используются самыми популярными сервисами, одинаковы для подавляющего большинства устройств
2) Зарегестрированные порты - свободные для регистрации порты для разработчиков веб-приложений
3) Динамические порты - basically, все остальные возможные, назначаются ОС клиенту

Транспортный уровень может обеспечить надежность передачи данных выще, чем у лежащей в его основе сети

Гарантия доставки данных:
- Подтверждение получения
- Повторная отправка не подтвержденных данных

Гарантия порядка следования сообщений:
- Нумерация сообщений

## UDP

UDP (User Datagram Protocol) - протокол датаграм пользователя. Сообщения UPD называются датаграммами (аналогия с телеграммой)

Особенности UDP:
* Нет соединения
* Нет гарантии доставки данных
* Нет гарантии сохранения порядка сообщений

Надежность доставки по сравнению с IP не повышается

Формат заголовка UDP
![](https://i.imgur.com/jn2S1yT.png)

**Преимущество UDP - скорость работы**, так как нет расходов на установку соединения. Ошибки в современных сетях происходят редко, а если они и есть, то ошибки может обработать приложение.

Область применения UDP - короткие запросы-ответы. Яркий пример - DNS (порт 53):
![](https://i.imgur.com/nMCzfqL.png)

## TCP

### TCP (Transmission Control Protocol) - протокол управления передачей.

TCP ++гарантирует++ доставку данных и сохранение следования сообщений.

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

Для гарантии доставки данных TCP использует сообщения подтверждения доставки (**ACK**nowledgement). После отправки каждого сегмента данных отправитель ждет подтверждение принятия этого сегмента и если оно не приходит, отправляет данные снова.

В протоколе TCP подтверждается не каждый сегмент, а несколько сегментов, отправленных друг за другом. Это называется "Механизм скользящего окна".

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

В TCP сообщения нумеруются. Каждый сегмент содержит номер байта, указывающий на его положение в изначальном потоке байт.
![](https://i.imgur.com/3iFQP8b.png)

И так же при отправке подтверждений получения сегментов получатель отправляет номер байта который он ожидает получить следующим.
![](https://i.imgur.com/43MBSyW.png)

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

Перед отправкой данных по TCP необходимо установить соединение, чтобы:
* Убедиться, что отправитель и получатель хотят отправлять данные друг другу
* Договориться о нумерации потока байт
* Договориться о параметрах соединения (макс. размер сегмента и т.д.)


После завершения передачи данных соединение TCP должно быть разорвано.

### Скользящее окно

Гарантия доставки данных реализуется подтверждением доставки и повторной отправкой неподтвержденных сообщений. Варианты подтверждения:
* Остановка и ожидание (Wi-Fi, транспортный уровень)
* Скользящее окно (TCP, транспортный уровень)

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

В варианте со скользящим окном данные передаются сразу по несколько сегментов и подтверждаются тоже сразу несколько. 
![](https://i.imgur.com/yvpPmqa.png)

Есть два типа подтверждения, исп. в скользящем окне: 
1) Кумулятивное - подтверждение приема указанного байта данных и всех предыдущих, используется по умолчанию
2) Выборочное - подтверждение диапозоном принятых байт, эффейтивно при большом диапазоне байт

### Соединение в TCP

Перед отправкой данных в TCP необходимо установить соединение, а после окончания отправки - разорвать его.

Для этого ипользуется 3-way handshake.

1) Отправитель отправляет сообщение с флагом SYN, так же включая в сегмент порядковый номер отправляемого байта.
2) Получатель отвечает так же сообщением SYN, включая подтверждение предыдущего сообщения ACK и номер ожидаемого байта.
3) Отправитель отвечает на SYN получателя подтверждением ACK
![](https://i.imgur.com/31kuDWO.png)

В TCP соединение дуплексное, что значит, что данные могут передаваться в обе стороны.

Схемы разрыва соединения:
* Одновременное (обе стороны разорвали соединение)
* Одностороннее (одна сторона прекращает передавать данные, но может принимать)

Варианты разрыва соединения - FIN (односторонее закрытие), RST (разрыв из-за критической ситуации)

FIN: ![](https://i.imgur.com/BBM0cXK.png)


Если другая сторона также отправляет FIN, то соединение закрывается полностью. RST-сообщение же сразу перекрывает соединение в обе стороны.

### Формат заголовка TCP 

![](https://i.imgur.com/NgthHdP.png)

1) **Порты отправителя и получателя**
2) **Порядковый номер** - первый номер байта в сегменте. Размер сегмента в сети Ethernet, как правило, составляет 1460 байт, чтобы с заголовком TCP и IP можно было поместиться в кадр Ethernet размером 1500 байт
3) **Номер подтверждения** - используется для кумулятивного подтверждения, здесь указывается последний полученный байт + 1 (номер следующего ожидаемого байта) при отправке подтверждения
4) **Длина заголовка** - длина необязательного заголовка TCP
5) **Флаги TCP:**
    - NS, CWR, ECE - флаги для управления перегрузкой
    - URG - указывает на то, что в сегменте находятся данные, которые нужно немедленно передать приложению, **сейчас не используется**
    - ACK - флаг подтверждения
    - PSH - указывает, что полученные данные нужно передать приложению без записи в буфер, так же, как и флаг URG **сейчас не используется**
    - RST, FIN - используются для разрыва соединения
    - SYN  - используется для установки соединения
6) **Размер окна** - используется для управления потоком
7) **Контрольная сумма** - исп. для проверки целостности доставленных данных
8) **Указатель на срочные данные** - завершает обязательную часть заголовка
9) **Параметры:**
    - MSS (Макс. размер сегмента) - говорит о том, сегмент какого размера может принять получатель
    - Масштаб окна - позволяет указать макс. размер окна достпуного для получения байт
    - Выборочное подтверждение - позволяет отправлять подтверждение диапазона байт, а не всех данных до опр. байта
    - Метки времени
10) **Данные**

### **Управление потоком в TCP**

В сети могут быть устройства разной производительности. Управление потоком (flow control) - это предотвращение "затопления" медленного получятеля быстрым отправителем. Также благодаря контролю потока приложения, к которым отправляются данные, могут считывать их не сразу, а через какое-то время.

Получатель может указать размер окна, чтобы давать знать отправителю, сколько данных он может принять в данный момент. Таким образом, получатель, получив какое-то кол-во данных, может отправить отправителю сообщение с размером окна равным нулю, что говорит о том, что передачу данных надо остановить, пока данные не обработаются. 
![](https://i.imgur.com/mDpwmpT.png)

Если новый размер окна долго не приходит, отравитель может запросить подтверждение того, что размер окна все еще равен нулю - Zero Window Probe.
![](https://i.imgur.com/wt45R0z.png)

### **Управление перегрузкой**

При передаче сегментов пачками сеть, через которую передается множество таких сегментов, может перегрузиться. Для этого при формировании размера окна учитывается загрузка сети. Это определяется динамически и используется так называемое ++окно перегрузки++. Оно находится на стороне отправителя и его размер рассчитывается в зависимости от того, какая в данный момент нагрузка на сеть. Оба окна используются для решения более общей задачи - управление скоростью передачи данных в сети. ~~Есть два стула:~~
* Маленький размер окна - сегментов отправляется мало, не полностью используется пропускная способность сети. Результат - низкая скорость передачи данных.
* Большой размер окна - сегментов в сеть отправляется слишком много, происходит перегрузка и маршрутизаторы отбрасывают пакеты. Результат - низкая скорость передачи данных

Для определения оптимального размера окна в TCP используется метод AIMD (Аддитивное увеличнение, мультипликативное уменьшение). При получении каждого подтверждения размер окна увеличивается, а при перегрузке размер окна умножается на значение <1 (1/2 чаще всего).
График работы AIMD:
![](https://i.imgur.com/4W2YyqW.png)

В качестве сигнала о перезгрузке чаще всего используется **сигнал о потере сегмента** - в современных сетях чаще всего потеря происходит не из-за ошибки канала, а из-за того, что сеть перегружена. Также может использоваться сигнал задержки сегмента и сигнал от маршрутизатора.

Проблема AIMD - медленный (линейный) размера окна перегрузки, этот метод хорошо работал на медленных сетях, но сейчас сети быстрые и он уменьшает максимальную скорость передачи данных на быстрых и надежных каналах. Для этого используется метод **медленного старта**. При медленном старте при каждом подтверждении размер окна увеличивается не на один сегмент, а на 2. Благодаря этому происходит экспоненциальный рост размера окна, но после сигнала о перезгрузке размер окна обнуляется и все начинается с начала. 

Использование медленного старта вместе с аддитивным увеличением дает график:
![](https://i.imgur.com/f3mRimG.png)

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

## Интерфейс сокетов

Сокеты впервые появились в ОС Berkley UNIX 4.2 BSD (1983 г.)
- Сокет в UNIX - файл специального вида
- Все, что записывается в файл, передается по сети
- Передача данных по сети скрыта от программиста

Сокеты - де-факто стандарт взаимодействия с транспортными протоколами.

Операции сокетов в UNIX, которые используются в большинстве реализаций сокетов в принципе:
![](https://i.imgur.com/cnRDjM9.png)

Рассмотрим пример взаимодействия клиента и сервера через сокеты.

На сервере создается сокет и привязывается к опр. адресу:порту методом bind. Вызов listen говорит о том, что сокет ++готов++ принимать соединения по сети, при этом вызове создается очередь для соединений. Затем сервер вызывает метод accept, что значит, что сервер ++будет++ принимать запросы на установку соединения.
![](https://i.imgur.com/ckeWQCG.png)

Клиент со своей стороны вызывает метод socket для создания сокета, и команду bind прописывать не обязательно - адрес и порт назначаются ОС. После создания вызывается метод connect, в котором указываются ip-адрес и порт сервера. Далее отправляется запрос на соединение. Сервер, принимая запрос, чтобы иметь возможность принимать соединения от нескольких клиентов, создает для каждого запроса копию сокета и соединение устанавливается с копией. 
![](https://i.imgur.com/f5wQKD3.png)

Клиент подготавливает порцию данных, отправляет их методом send, а сервер получает их методом recieve. Клиент и сервер могут обмениваться таким образом данными, и когда все данные переданы, клиент вызывает метод close, разрывающий соединение.
 

