Интернет, несомненно, является величайшим изобретением в истории человечества.Он соединяет между собой сотни миллионов компьютеров и устройств связи по всему миру, и даже пользователи на противоположных концах земли могут общаться в одно мгновение.
Можно сказать, что «протокол» — это ядро, поддерживающее упорядоченную работу такой большой и сложной системы, а так называемый «протокол» — это правила, которые должны соблюдать обе стороны. в разные ответы действие.
Короче говоря, «протокол» означает, что если отправитель и получатель отправляют пакеты данных в соответствии с этим правилом, они могут получить некоторые специальные функции или услуги поверх базовой передачи данных, иначе ваши данные не будут доступны другим. Например, обе стороны, которые следуют протоколу TCP, могут получить возможность надежной передачи данных при ненадежной сетевой передаче.
Вся компьютерная сеть многоуровневая.Есть семиуровневые модели и пятиуровневые модели.Лично я думаю, что пятиуровневую модель легче понять. Вводим эти пять слоев сверху вниз, они,Прикладной уровень, транспортный уровень, сетевой уровень, канальный уровень и физический уровень.
прикладной уровень
«Прикладной уровень» — это ближайший к пользователю уровень, и каждый процесс на хосте составляет «прикладной уровень». Например, если вы введете «www.baidu.com» в адресную строку своего браузера, что ваш браузер будет делать на прикладном уровне?
Во-первых, браузер будет использовать протокол DNS для возврата IP-адреса, соответствующего доменному имени «www.baidu.com».Мы подробно рассмотрим DNS позже.
Затем прикладной уровень решает создать «сокет TCP», а затем инкапсулирует действие запроса в дейтаграмму Http и помещает ее в сокет.
Существует два типа сокетов: «сокеты TCP» и «сокеты UDP». Прикладной уровень может отправлять десятки дейтаграмм одновременно, а транспортный уровень также получает все ответные сообщения. Так как же он различает, кто является ответом? пакеты для этих пакетов?
Сокет используется для различения каждого приложения прикладного уровня и часто идентифицируется по номеру порта и IP-адресу.Транспортный уровень может узнать, в какой сокет отправить сообщение, по номеру исходного порта и IP-адресу ответного сообщения. слово.
Когда дейтаграмма прикладного уровня помещается в сокет, вся работа прикладного уровня завершается, и его не волнует местонахождение последующих пакетов.
Здесь также следует отметить, что существенное различие между «сокетами TCP» и «сокетами UDP» заключается в том, что первый обеспечивает надежную доставку дейтаграмм к месту назначения, но требует времени, а второй не гарантирует дейтаграммы. достигают места назначения, но скорость высокая, что также является моментом, который протокол прикладного уровня должен учитывать при выборе протокола транспортного уровня.
Что касается TCP и UDP, мы продолжим говорить об этом позже.Давайте посмотрим, как работает протокол разрешения доменных имен DNS и как он разрешает доменное имя обратно в его IP-адрес.
Как работает DNS
Первое, что нужно уяснить, это то, что DNS — это протокол прикладного уровня, а протокол транспортного уровня, который он выбирает, — UDP, поэтому процесс разрешения вашего доменного имени, как правило, будет быстрым, но часто будут возникать сбои разрешения, но обновите его, и он будет будь в порядке.
На DNS-сервере доменное имя и соответствующий ему IP-адрес хранятся в виде записи, и невозможно, чтобы все записи хранились только на одном сервере.Я считаю, что каким бы мощным ни был сервер, он не может выдержать сотни миллионы одновременных транзакций в мире. Измерьте это.
Вообще говоря, существует три типа DNS-серверов:Корневые DNS-серверы, DNS-серверы домена верхнего уровня и полномочные DNS-серверы.
Среди них DNS-сервер домена верхнего уровня в основном отвечает за доменные имена верхнего уровня, такие как com, org, net, edu и gov.
Корневой DNS-сервер хранит IP-адреса всех DNS-серверов домена верхнего уровня, что означает, что вы можете найти серверы домена верхнего уровня через корневой сервер. Например: «www.baidu.com», корневой сервер вернет IP-адреса всех серверов домена верхнего уровня обслуживания com.
Затем вы произвольно выбираете один из серверов домена верхнего уровня и запрашиваете сервер домена верхнего уровня.После того, как сервер домена верхнего уровня получит доменное имя, он сможет принять решение и указать адрес ответственного полномочного сервера. для текущего домена.В качестве примера возьмем Baidu, сервер домена верхнего уровня вернет адреса всех авторитетных серверов, ответственных за домен baidu.
Таким образом, вы можете произвольно выбрать один из адресов авторитетного сервера, продолжить запрашивать у него конкретный IP-адрес «www.baidu.com», и, наконец, авторитетный сервер вернет вам конкретный IP-адрес.
До сих пор мы кратко описали общий процесс разрешения доменного имени, и некоторые детали не были упомянуты.Мы рассмотрим его полностью на примере.Далее описывается очень важная концепция.
Во всем процессе разрешения DNS есть очень важный человек, которого мы не представили.Это как «помощник» хоста, помогающий хосту запрашивать IP-адрес доменного имени. Он называется «локальный DNS-сервер».
Каждый раз, когда вы динамически получаете IP-адрес через DHCP, мы поговорим об этом позже. На самом деле маршрутизатор не только возвращает вам IP-адрес, но и сообщает вам адрес DNS-сервера, который является вашим локальным адресом DNS-сервера, то есть все ваши запросы на разрешение доменного имени должны сообщать только его, и он поможет вам проверить и сопоставить Вернуть результат вам.
Кроме того, локальный DNS-сервер часто имеет функцию кэширования, обычно записи в течение двух дней будут кэшироваться, поэтому большую часть времени вы не можете почувствовать процесс разрешения доменного имени, потому что оно часто берется из кэша, что очень быстро .
Давайте рассмотрим простой случай:
Нашел картинку в интернете.Сам рисует слишком долго,но для иллюстрации задачи достаточно.Теперь предположим,что запрашивается "www.xx.com".
- ①: Хост отправляет сообщение с запросом в свой собственный локальный DNS, если на локальном сервере есть кеш, он напрямую возвращает результат.
- ②: Локальный сервер обнаруживает, что в кеше ничего нет, поэтому он выбирает один из встроенного списка корневых серверов для отправки сообщения запроса.
- ③: Корневой сервер анализирует суффикс имени и сообщает локальному серверу, что он отвечает за список всех серверов верхнего уровня для .com.
- ④: Локальный сервер выбирает сервер домена верхнего уровня для продолжения запроса, сервер домена .com продолжает разрешать запросы после получения доменного имени и возвращает список всех авторитетных серверов, ответственных за домен .xx.
- ⑥: локальный сервер снова отправляет сообщение с запросом с одного из возвращенных авторитетных серверов и, наконец, получает конкретный IP-адрес с авторитетного сервера.
- ⑧: вернуть результат хосту
Фактически, весь процесс отправки и ответа на сообщения DNS основан на нашем пятиуровневом протоколе, но основное внимание здесь уделяется пониманию самого протокола DNS, поэтому конкретные детали других уровней не упоминаются. Напоминаем, что DNS — это только протокол прикладного уровня.
транспортный уровень
Задача транспортного уровня состоит в том, чтобы собрать все дейтаграммы, выталкиваемые из сокета прикладным уровнем, повторно инкапсулировать дейтаграммы прикладного уровня в соответствии с протоколом транспортного уровня, указанным прикладным уровнем, TCP или UDP, и отправить их на сетевой уровень для отправки.
TCP и UDP — это два протокола на транспортном уровне.Первый — это надежный протокол передачи на основе соединения, а второй — ненадежный протокол передачи без установления соединения.Поэтому первый больше подходит для случаев, когда требуется высокая целостность данных, а второй подходит для сценариев, допускающих потерю данных, но требующих особенно высокой скорости передачи, таких как голосовые вызовы, видео и т. д., безвредна потеря одного или максимум двух пакетов на некоторое время.
UDP
UDP не так сложен, как TCP, он не гарантирует ни надежной передачи данных в пункт назначения, ни гарантии того, что данные прибудут в пункт назначения по порядку, а лишь обеспечивает простую проверку ошибок. Формат сообщения следующий:
Среди них данные — это данные, передаваемые прикладным уровнем, номер порта источника используется для доставки ответного сообщения, номер порта назначения используется для доставки данных в процесс назначения, а контрольная сумма используется для проверки того, поврежден в процессе передачи. , UDP сразу отбрасывает пакет.
TCP
Протокол TCP немного сложнее.Он ориентирован на установление соединения и предоставляет надежные услуги передачи данных на основе соединений.Его формат пакета данных выглядит следующим образом:
Просто объяснять значение каждого поля в формате сообщения не очень практично, и вам будет трудно его понять. повторная передача при потере пакетов» и т. д. Во время действий будет постоянно объясняться, как использовать соответствующие поля в сообщении во время этих действий.
Прежде всего, давайте взглянем на хорошо известное «трехстороннее рукопожатие», которое в основном является синонимом TCP.Неважно, понимают ли люди конкретные принципы или нет, когда дело доходит до TCP, они в основном знают -способ рукопожатия».
и сам,Трехстороннее рукопожатие TCP должно гарантировать, что обе стороны могут установить стабильное соединение и выполнить действия запроса и ответа пакетов данных., а почему рукопожатие трехкратное, а не четырех-пятикратное, это вопрос философский, поэтому здесь я его обсуждать не буду.
первый шаг:
Клиент отправляет на сервер специальное сообщение TCP.Сообщение не содержит данных прикладного уровня, но является специальным сообщением.Значение поля SYN в его заголовке TCP равно 1 (см. формат сообщения выше).
Кроме того, клиент случайным образом сгенерирует начальный порядковый номер и заполнит его в поле «Порядковый номер» сообщения, что означает, что порядковый номер текущего сообщения такой, и мои последующие пакеты будут увеличиваться на основе этой последовательности номер.
Затем сообщение будет отправлено на сервер через сетевой уровень, канальный уровень и физический уровень.
Шаг 2:
Если пакет потерян, клиент попытается отправить его снова через определенный интервал.
Если пакет поступает на сервер точно, сервер откроет TCP-заголовок и увидит, что это специальное SYN-сообщение рукопожатия, поэтому для этого соединения выделяются такие ресурсы, как кеш.
Затем сервер начинает формировать ответное сообщение. SYN — это поле, используемое для синхронизации. В ответном сообщении по-прежнему будет установлено значение 1, и сервер также случайным образом сгенерирует начальный порядковый номер и поместит его в поле порядкового номера ответа. сообщение.
Наконец, сервер также присвоит значение полю подтверждения в ответном сообщении, которое представляет собой значение серийного номера, отправленного клиентом, плюс один.
Общий смысл таков: «Я согласен с вашим запросом на подключение, мой начальный серийный номер xxx, я получил ваш начальный серийный номер, я жду прибытия вашей следующей группы».
третий шаг:
Клиент получает ответное сообщение от сервера, поэтому он выделяет ресурсы, такие как буферизация, необходимые для TCP-соединения клиента, поэтому соединение установлено.
Фактически, начиная с третьего шага, клиент может нести данные прикладного уровня для обмена сообщениями с сервером.В каждом последующем сообщении SYN равен 0, потому что он используется только для синхронизации начального порядкового номера, который требует очистки.
В целом весь процесс «рукопожатия» выглядит примерно так:
Давайте взглянем на «четыре волны» процесса разрыва TCP-соединения.
Поскольку TCP-соединение потребляет много ресурсов хоста, не только серверу необходимо выделять различные ресурсы кэша, но и клиенту также необходимо выделять соответствующие ресурсы. Поскольку TCP представляет собой «полнодуплексную связь», сервер и клиент на самом деле одно и то же, и кто является клиентом, а кто сервером, является относительным.
Этот момент подчеркивается, чтобы показать, что TCP-соединение может быть разорвано не только клиентом, но и сервером.
Здесь мы предполагаем, что клиент активно инициирует запрос на отключение в качестве примера:
первый шаг:
Клиент создает специальное TCP-сообщение с полем заголовка FIN, установленным в 1, и отправляет сообщение.
Шаг 2:
Сервер получает специальное сообщение FIN, поэтому он отвечает клиенту сообщением ACK, сообщая клиенту, что сообщение с запросом на завершение работы получено и я его обрабатываю.
третий шаг:
Сервер отправляет сообщение FIN, чтобы сообщить клиенту, что я собираюсь закрыть соединение.
четвертый шаг:
Клиент возвращает ответное сообщение ACK, сообщая серверу, что я получил сообщение, которое вы только что отправили, и я подтвердил, что вы можете закрыть соединение.
Когда сервер получает ответное сообщение ACK, отправленное клиентом, он освобождает все ресурсы, используемые сервером для соединения TCP.
Опиши это более интуитивно с помощью картинки:
В сочетании с изображением и соответствующей информацией о серийном номере, давайте подробно поговорим о некоторых деталях.
Сначала клиент отправляет специальный пакет с порядковым номером u. После завершения передачи клиент переходит в состояние FIN-WAIT-1.В этом состоянии клиент TCP-соединения больше не может отправлять дейтаграммы, но может принимать дейтаграммы.Он ожидает ответного сообщения от сервера.
Затем сервер получает запрос сообщения о завершении соединения, отправленный клиентом, сервер строит ответное сообщение, сообщает клиенту «Я получил все пакеты до серийного номера u+1» и входит в состояние ЗАКРЫТО-ОЖИДАНИЕ, которое продолжается Времени мало.
Затем сервер отправит свою дейтаграмму FIN, чтобы уведомить клиента о том, что сервер собирается закрыть соединение, а затем войдет в состояние LAST_ACK, чтобы дождаться ответного сообщения клиента.
Как только клиент получит это сообщение FIN, он вернет подтверждающее сообщение и войдет в состояние TIME-WAIT, ожидая, пока интервал времени 2MSL полностью освободит ресурсы, занятые TCP-соединением клиента.
В то же время, когда сервер получит последнее подтверждающее сообщение от клиента, он напрямую отключит сервер и освободит соответствующие ресурсы.
Что касается того, почему клиенту нужно ждать 2MSL, прежде чем полностью освободить ресурсы, связанные с TCP?
Это связано с тем, что 2MSL — это максимальное время существования пакета в сети, и пакеты, поступающие после этого времени, будут отбрасываться, и если последний пакет подтверждения клиента будет потерян в сети, сервер инициирует повторную отправку пакета. третья волна, и ожидающий клиент может немедленно повторно отправить запрос на подтверждение.
Вот почему клиент ожидает максимальное время передачи пакета. Некоторые люди могут задаться вопросом, почему предыдущие запросы не ждали тайм-аута, а только последняя передача данных ждала тайм-аут?
На самом деле, причина очень проста, я думаю, вы также можете подумать об этом, то есть у TCP есть свои собственные возможности синхронизации.Если подтверждающее сообщение определенного сообщения не получено через определенный период времени, оно будет автоматически resent, а если соединение сразу закрывается без ожидания, то Как мне узнать, получил ли сервер мое подтверждающее сообщение или нет?
Ожидая самый длинный период, если запрос сообщения от сервера не получен в течение этого периода, то наше подтверждающее сообщение должно было прийти на сервер, иначе оно может быть отправлено повторно.
До сих пор мы кратко описывали «трехстороннее рукопожатие» и «четырехстороннюю волну» TCP, давайте рассмотрим некоторые другие особенности TCP, такие как: надежная передача, контроль перегрузки и т. д.
Во-первых, давайте посмотрим, как TCP обеспечивает надежную передачу, то есть как решить проблему потери пакетов при передаче по сети.
TCP использует протокол «обратных N шагов» для достижения надежной передачи, если быть точным, TCP частично оптимизирован на его основе.
Протокол «запасных N шагов» также известен как протокол «скользящего окна», то есть отправителю разрешено иметь не более N «отправленных, но не подтвержденных» пакетов данных. p3 равно N, окно здесь относится к интервалу от p1 до p3.
Только когда отправитель получает сообщение с подтверждением от p1, все окно может скользить вперед. Фактически, до получения сообщения с подтверждением от p1, даже если было получено следующее сообщение, сервер только кэширует его. Эти «неожиданные сообщения "
До тех пор, пока сервер не получит минимальное ожидаемое сообщение, он извлекает последующие сообщения, пришедшие из кэша, объединяет их и доставляет наверх, а затем возвращает отправителю подтверждающее сообщение.
Когда окно отправителя было подтверждено для нескольких последовательных сообщений слева направо, все окно сдвинется вперед на несколько единиц длины.
Давайте посмотрим на пример:
Это окно отправителя.Серым цветом отмечены сообщения, которые были подтверждены, желтым – сообщения, которые были отправлены, но не подтверждены, зеленым – следующее сообщение, которое нужно отправить, а белым – недоступные сообщения.
Это мы предполагаем, что сервер получил два пакета 6 и 7, но в прошлый раз он доставил пакет № 4 на прикладной уровень, то есть ожидает пакет № 5, поэтому временно отправить 6 на прикладной уровень. , 7 и два пакета кэшируются и доставляются на прикладной уровень, когда приходит пакет № 5.
Теперь сообщение № 5 было повторно передано из-за тайм-аута и, наконец, достигло адресата.И верните подтверждающее сообщение, ACK = 8, указывающее, что все сообщения до серийного номера 8 были получены..
Когда отправитель получает подтверждающее сообщение, 5, 6 и 7 становятся серыми, а окно перемещается вперед на три единицы.
Кроме того, я хотел бы подчеркнуть, что TCP не имеет отрицательных подтверждений, поэтому, если несколько пакетов, на которые постоянно отвечает сервер, являются подтверждениями для одного и того же порядкового номера, очень вероятно, что пакет после порядкового номера будет потерян.
Например: если сервер отправляет несколько ACK для пакета 5, что это значит? Это означает, что полный порядковый номер восходящей доставки моего сервера - № 5. Последующие сообщения мне не поступали, лучше отправить еще раз и не ждать таймаута.
Это также является основным принципом «быстрой повторной передачи».
Итак, мы в основном ввели надежную передачу TCP.Давайте посмотрим, как TCP контролирует отправляемый трафик, когда сеть перегружена?
TCP считает, что потеря пакетов означает перегрузку, и эффективность передачи необходимо снизить, и каждый раз, когда принимается дейтаграмма подтверждения, сеть считается гладкой, что повысит эффективность передачи.
Алгоритм управления перегрузкой TCP состоит из трех частей:Медленный старт, предотвращение перегрузок и быстрое восстановление.
медленный стартИдея состоит в том, что в начале медленной передачи, например, за определенный период времени отправляется только одна дейтаграмма, а при получении подтверждающего сообщения в следующий раз в течение того же временного интервала будут отправлены две дейтаграммы с удвоенной скоростью. быть отправлены и так далее.
Таким образом, за короткий промежуток времени отправитель TCP-соединения будет увеличиваться в геометрической прогрессии, но как только пакет будет потерян, он получит избыточное подтверждение ACK, или подтверждение ACK для пакета никогда не было получено и должен начать тайм-аут. отправитель думает, что "сеть перегружена".
Таким образом, скорость устанавливается непосредственно на единицу, то есть на период времени приема-передачи, отправляется только один пакет, и устанавливается переменная ssthresh для выражения концепции порога, который составляет половину скорости отправки отправителя, когда последний пакет был потерян.
Эффективность отправки последующих отправителей также будет увеличиваться экспоненциально, но в отличие от первого раза, как только этот порог будет достигнут, TCP перейдет в режим «предотвращения перегрузки», и эффективность отправки в этом режиме больше не будет увеличиваться экспоненциально, а будет расти осторожно.
предотвращение перегрузкиИдея состоит в том, что после того, как все дейтаграммы, отправленные в каждом периоде времени приема-передачи, подтверждены, в следующий раз отправляется еще один пакет, поэтому эффективность медленного роста является разумной.
Затем, как только отправитель истечет и потеряет пакеты, обратите внимание, что это тайм-аут, установите скорость отправки на единицу и снова войдите в состояние медленного запуска, а порог равен половине текущей эффективности отправки.
Если сервер возвращает несколько избыточных ACK, чтобы уточнить, что вы потеряли пакеты, TCP не считает это серьезным, В этом случае TCP вдвое снижает текущую эффективность отправки и переходит в фазу быстрого восстановления.
быстрое восстановлениеОсновная идея заключается в том, что получение нескольких избыточных ACK повысит эффективность отправки нескольких пакетов.То есть, разве ваш сервер не получил несколько моих пакетов?Я отправлю вам два раза с увеличенной скоростью и отправлю их тебе быстро..
Когда происходит потеря пакетов, вызванная тайм-аутом отправителя в течение этого периода, таким же образом начальная скорость отправки уменьшается вдвое, а текущая эффективность отправки берется в качестве порога, и вступает в стадию медленного старта.
Конечно, если в течение этого периода будет получено подтверждение потерянного пакета, эффективность передачи будет соответствующим образом снижена, и будет введено состояние предотвращения перегрузки.
Таким образом, были представлены основные идеи всего TCP, и весь транспортный уровень в основном прояснился. Про транспортный уровень у вас должно быть определенное представление, подытожу.
Задача транспортного уровня состоит в том, чтобы получить все данные, которые необходимо отправить, из сокетов различных процессов прикладного уровня, а затем выбрать TCP или UDP для инкапсуляции и передачи данных на нижний сетевой уровень для отправки.
Не закончено, продолжение следует. . .
Весь код, изображения, файлы в статье хранятся в облаке на моем GitHub:
(https://github.com/SingleYam/overview_java)
Добро пожаловать в публичный аккаунт WeChat: Gorky on the code, все статьи будут синхронизированы в публичном аккаунте.