Транспортный уровень — протоколы TCP, UDP и все такое. Максимально просто (я старался)
Зачем?
Вообще, да, транспортный уровень (кстати, это четвертый уровень модели OSI, о которой я наверняка когда-то напишу) — это не тот уровень, на котором работает наш любимый HTTP (о котором подробнее здесь). Точнее, вообще-то, он работает поверх TCP — и именно поэтому я решил немного разобрать и его тоже. Не то чтобы это напрямую важно для Node.js-разработчика, но мы здесь в том числе про эрудицию, поэтому давайте вкуривать.
TCP
Расшифровывается TCP как Transmission Control Protocol (протокол управления передачей) — и используется почти везде в интернете (ну, там, где не используется UDP, о котором чуть позже). Если сильно вкратце, то TCP устанавливает соединение (и это важное его отличие от UDP, которому это не нужно) и обменивается по этому соединению пакетами (которые почему-то называются сегментами).
Собственно, это самое установление соединения несколько замедляет процесс передачи данных, но дает неоспоримое преимущество перед тем же UDP — TCP гарантирует доставку данных. Давайте попробуем разобрать процесс установки соединения и передачи данных по TCP.
TCP: состояния соединения
-
CLOSED
: начальное состояние соединения -
LISTEN
: сервер ожидает запросов -
SYN-SENT
: клиент отправил серверу запрос на создание соединения -
SYN-RECEIVED
: сервер получил запрос на создание соединения и отправил ответный запрос клиенту -
ESTABLISHED
: соединение установлено -
FIN-WAIT-1
: какая-то из сторон отправила запрос на завершение соединения -
CLOSE-WAIT
: другая сторона получила этот запрос, отправила в ответ пакет с флагом ACK и продолжает передачу данных -
FIN-WAIT-2
: первая сторона получила ACK и ждет пакета с флагом FIN, чтобы завершить соединение -
LAST-ACK
: вторая сторона заканчивает передачу данных и отправляет пакет FIN -
TIME-WAIT
: первая сторона получила пакет FIN, отправила пакет ACK и ждет закрытия соединения -
CLOSING
: обе стороны закрыли соединение
TCP: установка соединения
Установка соединения по TCP (handshake) состоит из трех шагов:
- клиент, желающий установить соединение с сервером в состоянии
LISTEN
, посылает ему сегмент с номером последовательности (такая штука, которая позволяет обеим сторонам считать количество переданных / полученных пакетов) и флагомSYN
. Соединение переходит в состояниеSYN-SENT
- сервер получает пакет, в случае успеха запоминает номер последовательности и посылает клиенту сегмент с номером последовательности и флагами
SYN
иACK
, а соединение переходит в состояниеSYN-RECEIVED
. В случае неуспеха сервер просто посылает пакет с флагомRST
- если клиент получает пакет
SYN
, он запоминает номер последовательности и посылает пакет с флагомACK
. Если клиент получает еще иACK
, то он переходит в состояниеESTABLISHED
. Если же он получает пакет с флагомRST
, то он прекращает попытки установить соединение. А если клиент не получает ничего в течение 10 секунд, он повторяет все заново - если сервер в состоянии
SYN-RECEIVED
получает от клиентаACK
, он переходит в состояниеESTABLISHED
. Иначе он по таймауту перейдет в состояниеCLOSED
(извините за всю эту сложность. Я описал все именно так только потому, чтобы было понятно, насколько времязатратно установление соединения по TCP. Это, к примеру, поможет нам понять преимущества HTTP/2 — подробности в статье об HTTP).
Что хочется добавить: TCP используется там, где гарантия доставки пакетов и их порядок гораздо важнее скорости. Для нас, как для веб-разработчиков, важнее всего, что его использует протокол HTTP.
UDP
UDP (User Datagram Protocol, протокол пользовательских диаграмм) — штука ощутимо более простая уже потому, что не требует установки соединения. Из этого следует, что он ощутимо быстрее. Из этого же следует, что он не гарантирует доставки пакетов и их порядка, в отличие от TCP.
UDP удобно использовать там, где скорость важнее, чем гарантия доставки — передача видео / аудио, разного рода игровых данных и прочего такого. UDP — несравненно более простая и топорная штука, чем TCP, но свое применение, конечно, находит. Нам, как веб-разработчикам, может быть интересно, что по UDP часто работает WebRTC, штука для передачи потоковых данных между браузерами.
Выводы
Если коротко: TCP медленнее за счет установки соединения, но гарантирует порядок доставки пакетов и саму их доставку. UDP тупее, но быстрее — он просто пуляет пакетами, куда ему скажешь.
Знать такие вещи нам, веб-разработчикам, надо в первую очередь потому, что поверх этих протоколов работают штуки, с которыми работаем мы (HTTP, WebRTC и так далее). Ну, и да, мы здесь еще и про кругозор, а не только про Node.js.
Интересный пост?
Вот еще похожие:
- Событийно-ориентированная архитектура и Node.js Events
- Реактивное программирование: теория и практика
- Как и зачем писать тесты?
- Функциональное программирование. Что это и зачем?
- Docker: что, зачем и почему