TCP и UDP, или Два столпа Интернета
В этой серии статей мы пытаемся описать, как работает CDN и какие технологии делают его существование возможным.
В предыдущей статье мы обсудили иерархию Интернета, разницу между средами передачи данных и путь запроса от компьютера пользователя до сервера, расположенного на другом конце земного шара. В этой поднимемся на несколько уровней выше, чтобы разобрать каким «языком» пользуются компьютеры, чтобы общаться друг с другом.
Невозможно по-быстрому рассказать обо всём, что касается устройства Интернета. Потому в этой и следующих статьях мы будем рассматривать только определённое подмножество технологий – часть между физическим уровнем и уровнем приложения.
Не будем говорить о том, как компьютеры используют электричество для представления и передачи данных. Это очень интересная тема, но слишком низкоуровневая для этого цикла.
Но и рассказывать про то, как браузер загружает страницы, тоже не будем. HTTP-запросы, сжатие, языки программирования, рендеринг страниц – всё мимо.
Что нам интересно, так это то, как данные находят путь от одного компьютера до другого.
Коммутация
Если вы достаточно стары, то скорее всего застали проводные телефоны, которыми раньше активно пользовалось человечество. А может, у вас даже до сих пор есть такой! В таком случае, скорее всего вы знаете, что вот ещё лет сто назад они работали в полуавтоматическом режиме.
Сперва вам нужно было поднять трубку и сказать телефонисту (который был реальным человеком), что вы хотите, чтобы вас соединили с вашим знакомым из другого города. Телефонист выслушал бы ваш запрос, повесил бы трубку, а позже перезвонил бы уже с вашим другом «на линии» (on line – пер.).
Чего вы возможно можете не знать, так это того, что происходило за кадром. А там телефонист переключал кабели между портами, чтобы соединить вас с вашим другом:

Телефонистки в Bell System обслуживают межконтинентальные звонки, 22 декабря 1943
То, что происходит на картинке – это коммутация каналов. Коммутация каналов – это способ соединения двух узлов сети, при котором между ними устанавливается выделенный канал связи. Через этот канал и происходит общение. Иными словами, когда вы звонили другу, кто-то или что-то в буквальном смысле строил путь из кабелей между вами.
Как нетрудно догадаться, подобный тип коммуникаций не очень-то подходит для Интернета, потому что мы постоянно подключаемся к огромному количеству серверов по всему миру. Строить такую высоконагруженную сеть на основе коммутации каналов было бы слишком безумно. Да и было бы слишком дорого создавать такую сеть, не говоря уже о её поддержке.
Вместо этого Интернет построен на основе коммутации пакетов. При таком способе построения сети, для создания соединения между двумя узлами не требуется физического переключения кабелей. Когда мы посылаем сообщение от одного компьютера к другому, это сообщение проходит через различные сети, каждая из которых сама решает, куда лучше его отправить.
С какой-то точки зрения это может звучать безумно, но по сути в Интернете нет какого-то главного «координатора», который бы решал, по какому пути каждый пакет должен идти. Наш компьютер просто «бросает» пакет в сеть, и все устройства, через которые он проходит, пытаются решить, какой путь для этого пакета будет наиболее оптимальным. Удивительно, но в большинстве случаев, у этих устройств получается достигнуть поставленной цели. Всё благодаря протоколам!
Протоколы
Протокол – это набор правил, определяющий, как узлы сети должны передавать данные друг другу. Вы скорее всего слышали про высокоуровневые протоколы – HTTP, SSH, IMAP, DHCP.
В сфере телекоммуникаций огромное количество протоколов, каждый из которых решает какую-то свою задачу. Из-за того, что их много, есть даже специальные модели, определяющие «уровни протоколов». Если представить, что ваше сообщение, – это конфета, то протоколы в каком-то плане играют роль обёрток для этой конфеты.
Предположим, что вы заказали в подарок своему другу большую плитку вкусного шоколада от местной шоколадной фабрики.
Первым делом плитку шоколада запакуют в обёртку. Затем всё это положат в брендированный пакет. После этого, кто-нибудь в отделе доставки увидит, что это шоколадка – подарок, а потому пакет дополнительно украсят, дабы всё выглядело подобающе. Наконец, фабрика передаст пакет с подарком почтовой компании.
Почтовая компания же, получив пакет, запакует его в коробку и напишет на ней адрес вашего друга. Наконец, они погрузят всё это в грузовик и отправят в точку выдачи.
Когда грузовик приедет в точку выдачи, процесс пойдёт в обратную сторону: сперва выгрузят, потом проверят адрес получателя, распакуют коробку и так далее.
Весь этот процесс оборачивания-разворачивания шоколадки – ровно то, как работают протоколы в Интернете:

Ну, исключая тот факт, что с протоколами всё куда сложнее, чем с шоколадками
История OSI и TCP/IP
Так сложилось, что есть две модели, описывающие уровни протоколов. Одна из них теоретическая – модель OSI, а другая практическая – TCP/IP.
В 70-80-х годах прошлого столетия в сфере телекоммуникаций было много проблем, но и много возможностей. Тогда ещё не было такого Интернета, каким мы его знаем сегодня. Была лишь куча сетей, созданных разными компаниями. И этим сетям нужен был какой-то общий «язык» для общения, или скорее стандарт. А потому многие инженеры работали над тем, чтобы этот самый стандарт создать. Если говорить грубо, то для нас важно то, что в конечном итоге эти люди разделились на две группы.
Первая верила, что подобный стандарт должен создаваться открыто, со всеобщим обсуждением, с решением всех возникающих проблем и вопросов. Чтобы всем было удобно. Эта группа назвала стандарт, который она пыталась создать, – OSI, или Open Systems Interconnection.
Другая группа пошла иным путём, и начала разрабатывать и тестировать протоколы на основе тех сетей, что у них уже были. Так они создали TCP – Transmission Control Protocol, и IP – Internet Protocol. Изначально эти два протокола были частью одного большого, но впоследствии были разбиты на два для упрощения работы с ними.
Эта группа успешно протестировала протокол и перевела сети, которые были под её руководством, на него. Это случилось первого января 1983-го года. Так что, можно сказать, что это день, когда родился Интернет.
После этого TCP/IP начал набирать популярность, потому что он «просто работал». Плюс, эта модель была бесплатной, в то время как авторы OSI хотели взимать деньги со всех, кто пользовался бы их стандартами.
И что в итоге стало с OSI? Инициатива провалилась. Из-за идеи «открытости» те, кто принимал тогда решения, потратили очень много времени на обсуждения и споры. Часть из них лоббировали идеи, которые были выгодны большим корпорациям. Из-за других же дискуссии постоянно увязали в обсуждении незначительных деталей.
Однако, несмотря на то, что OSI как сетевая модель не нашла своего применения в реальном мире, она всё ещё остаётся хорошей теоретической моделью, описывающей уровни протоколов. Но модель, которая была имплементирована и захватила мир – TCP/IP.
Вот, как выглядят уровни протоколов в этих моделях:

TCP/IP
Обычно, когда обсуждают OSI и TCP/IP, пытаются сравнить эти модели и найти соответствия между их уровнями. Хоть картинка выше и выглядит как сравнение, мы не будем этого делать, потому что то, как соотносятся их уровни, не особо важно для нашей статьи. Да и «многоуровневость» как таковая «может быть вредной», если верить RFC 3439.
Ключевые протоколы модели TCP/IP, очевидно, TCP и IP. Всё остальное в этой модели описано довольно туманно, и даже авторы учебников и справочников по сетям не могут сойтись на чётких названиях и количестве уровней в этой модели.
Есть ли физический уровень под уровнем сетевого доступа? Нужно ли вообще называть уровень сетевого доступа так, или это всё же «канальный уровень»? Вокруг TCP/IP много таких вопросов. Однако, всё это не так важно, потому что основная суть стека очень простая.
Предположим, есть два приложения в сети, которые хотят обменяться данными. Пусть один из них сгенерирует сообщение. Не важно, какое именно. Это может быть HTTP-запрос, а может и нет. Это сообщение генерируется на уровне приложения.

Дальше оно передаётся на транспортный уровень, где к нему добавляется TCP или UDP-заголовок. Этот заголовок содержит информацию о портах, которые используются приложениями, и некоторую другую информацию (но о ней чуть позже). В результате получается то, что обычно называется датаграммой или сегментом.

Затем, сегмент передаётся на межсетевой уровень. Там к нему добавляется IP-заголовок, содержащий адреса компьютеров, на которых запущены приложения, участвующие в этом обмене данными. Результат объединения сегмента и IP-заголовка обычно называется пакетом.
Справедливости ради, нет чёткой разницы между датаграммами, сегментами и пакетами. В большинстве случаев для простоты они все называются «пакетами». Термины «датаграмма» и «сегмент» используются, только когда нужно явно указать тип протокола, с которым мы имеем дело.

Наконец, пакет передаётся на канальный уровень, где кодируется и уходит по проводам в сторону точки назначения. Протоколы на этом уровне так же добавляют свой заголовок в каждый пакет, и в результате получается кадр (или «фрейм» – пер.).
Кадры обычно содержат не только заголовок, но и окончание. Например, Ethernet-кадр для нашего сообщения может выглядеть примерно так:

Масштаб на картинке не соответствует действительности, конечно же. В реальности сообщение куда больше, чем заголовки и окончания
Когда кадр передаётся от одного промежуточного узла сети к другому, эти узлы разбирают кадр на части, проверяют IP-заголовок пакета, определяют что с ним делать, а затем создают новый кадр для этого пакета и передают его следующему узлу.
Иными словами, когда путь сообщения выглядит как-то так:

Если вы не читали предыдущую статью, то знайте, что синий прямоугольник – это сервер Гугла. Автор этой статьи определённо точно непризнанный художник
То работа протоколов на пути этого сообщения выглядит так:

В начале и конце передачи участвуют протоколы всех уровней TCP/IP-стека. Промежуточные же ноды обычно работают только с протоколами канального и межсетевого уровней
Окей, теперь мы знаем, что модель TCP/IP определяет протоколы транспортного и межсетевого уровней, но не особо тщательно описывает протоколы прикладного и канального уровней. Давайте теперь посмотрим на транспортный уровень чуть поближе.
TCP и UDP
Транспортный уровень модели TCP/IP основан на двух китах: Transmission Control Protocol и User Datagram Protocol. Есть и другие протоколы на этом уровне (например, QUICK), но они не так часто используются.
Протоколы транспортного уровня используются для адресации пакетов с порта приложения отправителя на порт приложения получателя. Более того, протоколы этого уровня не знают ничего про различия в узлах сетей. Всё, что им требуется знать про адресацию, это то, что есть приложение, отсылающее сообщение, и оно для отправки использует какой-то порт. И приложение, которое получает сообщение, тоже использует какой-то порт. Основная «адресация внутри Интернета» же реализована на межсетевом уровне, и будет описана в следующей статье.
UDP куда «легче» и проще, чем TCP, но в то же время UDP не такой надёжный, как TCP. Чтобы посмотреть на разницу между ними поподробнее, давайте начнём с User Datagram Protocol.
User Datagram Protocol
Этот протокол используется для «связи без установки соединения» (connectionless communication – пер.). Один узел сети просто отсылает пакеты, адресуя их другому узлу. Отправитель не знает ничего о том, готов ли получатель к приёму пакетов, и вообще, существует ли этот получатель. Отправитель также не ждёт какого-либо подтверждения о том, что получатель принял предыдущие пакеты.
Пакеты, передаваемые с помощью UDP, иногда называются датаграммами. Этот термин обычно используется тогда, когда важно подчеркнуть, что пакет передаётся без установки соединения.
Заголовок UDP-пакета состоит из 8 байт, которые включают в себя:
Вот так просто. Типичная UDP-датаграмма выглядит так:

Payload – это полезная нагрузка; сообщение, которое датаграмма должна передать получателю
Пробуем
UDP-сервер очень просто поднять самому. Вот, например, такой сервер, написанный на Node.js ровно так, как об этом сказано в официальной документации:
Давайте ж запустим его:
Теперь мы можем использовать netcat для отправки датаграмм из соседнего окна терминала:
Наш сервер успешно логирует отправленные нами датаграммы после их получения:
Как видите из логов выше, netcat решил использовать порт 55823 для отправки пакетов. Если мы возьмём Wireshark и перехватим эти пакеты, то увидим следующее:

Быстрый гайд по Wireshark. Вверху – лог пакетов и его фильтр, под ним – содержимое выбранного пакета в логе. Данные в квадратных скобках не содержатся в пакете, а вычислены Wireshark. В самом низу – текстовое представление выбранного пакета.
Если не хотите поднимать Node.js-сервер и перехватывать трафик самостоятельно, но хочется потыкать в Wireshark, качайте дамп-файл.
Итак, что у нас тут? Порт отправителя – 55823, тот, что выбрал netcat. Порт получателя – 8082, тот, что указан у нас в настройках сервера. Длина пакета 48 байт, потому что 8 из них – это заголовок, а ещё 40 – наше сообщение. И в конце контрольная сумма, указанная netcat.
Как видите, в логе Wireshark нет никаких ответов от сервера, а потому клиент не может быть уверен, что сервер действительно получил его датаграммы. По этой причине UDP используется там, где не страшно потерять часть сообщений. Например, при видео- или аудио-стриминге. Да, можно использовать для этого и TCP, но, как вы увидите чуть через минуту, использование TCP замедлило бы в таком случае передачу данных.
Справедливости ради, хоть UDP и не предполагает наличия подтверждений о получении сообщений, мы всё ещё можем узнать о том, что получатель недоступен. С помощью ICMP. Попробуйте отправить сообщения используя netcat, не включив перед этим UDP-сервер, и посмотрите, что будет в логах Wireshark. Вот, что вы там увидите; а вот дамп-файл.
Transmission Control Protocol
Если UDP простой и не требующий установки соединения, то TCP – сложный и требующий. Перед тем, как начать передачу данных, клиент и сервер должны подключиться друг к другу и договориться о том, как они будут осуществлять эту самую передачу.
В отличие от датаграмм в UDP, пакеты, создаваемые TCP, называются сегментами.
А вот, некоторые из тех задач, что решает TCP во время передачи данных:
Убеждается в том, что сегменты доставлены в нужном порядке.
Убеждается в том, что они вообще доставлены.
Контролирует поток пакетов, чтобы не перегружать им узлы сети.
Работы много, а потому и заголовок у TCP как минимум 20 байт, а то и больше. Он включает в себя:
Почему данные делят на пакеты?
Вся информация в сетях как в локальных, так и в интернете передаётся не сплошным потоком, а разбивается на отдельные фрагменты, называемые пакетами. Иногда, в различных типах сетей, применяются другие названия: блоки, сегменты, кадры, ячейки. В чем смысл такой разбивки? Не проще ли передать файл целиком?


Да, файл передать целиком проще. Но система разбивки на пакеты обладает огромными преимуществами, в конечном итоге приводящими к существенному повышению скорости передачи информации. В самом деле, если между двумя точками сети нужно передать какой-то файл, то всегда имеется множество маршрутов, по которым это можно сделать. Всегда выбирается маршрут с наиболее высокой скоростью передачи. И пакет отправляется по нему. В следующую миллисекунду этот маршрут может уже не быть наилучшим, и следующий пакет уже будет отправлен по другому маршруту. Таким образом достигается наиболее рациональная загрузка сети и наивысшая скорость передачи данных.
Понятно, что если отправлять весь файл целиком, то не факт, что маршрут, бывший наилучшим на начало передачи данных, таковым останется. К тому же в случае сбоя на маршруте, если пакет данных придет повреждённым, его проще и быстрее переслать заново, чем пересылать целый файл. Даже ваш любимый струйный принтер Canon Pixma iX4000 получает задания на печать от компьютера или ноутбука пакетами, а не сплошным непрерывным потоком.
Типичный размер пакета: 1-2 КБайта. В конце пакета как правило записывается проверочная информация, которая и позволяет принимающему устройству определить, дошел ли пакет без ошибок. Там, например, может быть стоять шестнадцатеричное число, равное числу единиц в теле пакета. Подсчитав число единиц в пакете и сравнив с контрольным числом, приёмноё устройство сделает вывод о том, дошел ли пакет без повреждений.
Правила передачи пакетов данных в интернете описываются протоколом TCP/IP (Transmission Control Protocol/Internet Protocol).
ГДЗ по информатике 9 класс учебник Поляков, Еремин § 4. Глобальная сеть Интернет
Данные, передаваемые по Интернету, разбиваются на пакеты, чтобы обеспечить более надежную и эффективную передачу данных, уменьшить время задержки и повысить скорость передачи.
2. Какова роль маршрутизаторов?
Маршрутизаторы играют ключевую роль в передаче данных в компьютерных сетях. Они определяют лучший путь для передачи данных от отправителя к получателю, основываясь на информации, содержащейся в каждом пакете данных.
3. Какими способами можно подключить ноутбук к Интернету? Если все варианты доступны, какой вы выберете? Почему?
Ноутбук можно подключить к Интернету различными способами, например, через проводное подключение, беспроводное подключение Wi-Fi или мобильную связь. Если все варианты доступны, выбор будет зависеть от доступности и удобства использования в конкретной ситуации.
4. Приведите пример, когда компьютер может иметь несколько IPадресов.
Компьютер может иметь несколько IP-адресов, если он подключен к нескольким сетям или имеет несколько сетевых интерфейсов, каждый из которых может иметь свой IP-адрес.
5. Сколько битов в памяти нужно выделить для хранения IPадреса?
IP-адрес состоит из 32 бит (IPv4) или 128 бит (IPv6), поэтому для хранения IP-адреса необходимо выделить соответственно 4 байта или 16 байт.
6. Зачем нужны доменные адреса?
Доменные адреса нужны для привязки удобочитаемых и запоминающихся имен к IP-адресам, используемым в Интернете. Они помогают пользователям легче запоминать и находить ресурсы в Интернете, вместо того, чтобы запоминать длинные числовые IP-адреса.
Процесс передачи данных по сети
Назначение любой сети – обмен данными (информацией) между компьютерами.
Данные обычно содержатся в больших по размерам файлах (блоках). Однако сети не будут нормально работать, если компьютер посылает этот блок данных целиком. Существуют две причины, замедляющие работу сети при передаче по кабелю больших блоков данных.
Во-первых, такой блок, посылаемый одним компьютером, заполняет кабель и «связывает» работу всей сети, т.е. препятствует взаимодействию остальных сетевых компонентов до окончания передачи.
Во-вторых, возникновение ошибок при передаче крупных блоков приведет к повторной передаче всего блока. А если поврежден небольшой блок данных, то требуется повторная передача именно этого небольшого блока, что значительно экономит время.
Разбиение данных на небольшие управляемые блоки позволяет ускорить передачу и обеспечить практически одновременную передачу информации несколькими компьютерами. При этом компьютеры не тратят время на ожидание.
Эти небольшие блоки называются пакетами (кадрами). Пакет– основная единица информации в компьютерных сетях.
При разбиении данных на пакеты скорость их передачи возрастает настолько, что каждый компьютер в сети получает возможность принимать и передавать данные практически одновременно с остальными компьютерами.
Разбиение данных на пакеты осуществляет компьютер-отправитель (источник). На компьютере-получателе пакеты накапливаются и выстраиваются в должном порядке для восстановления исходного вида данных.
Пакеты могут содержать несколько типов данных:
информацию (например, сообщения или файлы);
определенные виды данных и команд, управляющих компьютером (например, запросы к службам);
коды управления сеансом (например, запрос на повторную передачу для исправления ошибки).
При разбиении данных на пакеты сетевая операционная система добавляет к каждому пакету специальную управляющую информацию. Она обеспечивает:
передачу исходных данных небольшими блоками;
сбор данных при получении в исходном порядке;
проверку данных после сборки на наличие ошибок.
Структура пакета.Любой пакет состоит из 3-х обязательных компонентов:
Заголовок. Заголовок содержит:
адрес источника, идентифицирующий компьютер – отправитель;
адрес место назначения, идентифицирующий компьютер получатель;
инструкции сетевым компонентам о дальнейшем маршруте данных;
информацию компьютеру-получателю о том, как объединить передаваемый пакет с остальными, чтобы получить данные в исходном виде.
Данные. Эту часть пакета составляет информация, которую необходимо передавать. В зависимости от типа сети её размер составляет от 512 байтов до 4(Кб).
Так как обычно размер исходных данных гораздо больше 4 Кб, для помещения в пакет их необходимо разбивать на мелкие блоки. При передаче объемного файла может потребоваться много пакетов.
Трейлер. Трейлер содержит информацию для проверки ошибок, обеспечивающую корректность передачи. Эта информация носит название циклический избыточный код (CRC). Это число, получаемое в результате математических преобразований над пакетом с исходной информацией. Когда пакет достигает место назначения, эти преобразования повторяются. Если результат совпадает с CRC, – пакет принят без ошибок. В противном случае необходимо повторить передачу пакета, поскольку при передаче данные изменились.