Я пытаюсь понять протоколы прикладного уровня в стеке TCP / IP. Я знаю, что протокол HTTP и DNS остаются на верхнем уровне (прикладной уровень). Поэтому, когда браузер хочет получить доступ к ресурсу, он должен отправить запрос на HTTP-сервер, например:
GET www.pippo.it/hello.htm HTTP/1.1
Делая этот запрос, следуя правилам протокола HTTP, он использует URL-адрес страницы, а не IP-адрес.
Я знаю, что DNS-запрос необходим для преобразования URL в IP. Итак, мой вопрос: HTTP вызывает протокол DNS? Это кажется мне невозможным, поскольку оба являются протоколами верхнего уровня (поэтому DNS не может предоставить службу HTTP). Точно так же даже TCP (который находится на более низком уровне) не может запрашивать услугу на протоколе более высокого уровня, таком как DNS.
Итак, когда происходит запрос DNS? А кто выполняет такой запрос?
источник
Ответы:
Данный HTTP-запрос на самом деле недействителен, если браузер не общается с посредником (прокси).
Ваш пример был бы похож на следующий, если бы браузер напрямую общался с веб-сервером:
Теперь, чтобы рассмотреть это в перспективе, рассмотрим модель OSI:
У нас есть 3 системы в действии:
Используемые протоколы, снизу вверх (минимальное значение для OP):
HTTP-связь осуществляется по протоколу TCP (TCP находится поверх IP-протокола), в то время как DNS-связь, в данном случае, осуществляется по протоколу UDP (UDP также находится поверх IP-протокола).
Вот последовательность общения вкратце:
Клиент , работающий браузер, запрашивает сервер DNS для
A
записи наwww.pippo.it
, используя протокол UDP.1.1. На клиенте именно операционная система выполняет решающую часть и обращается к браузеру - браузер никогда не обращается к DNS-серверу напрямую, а через ОС, вызывая gethostbyname () или более новый getaddrinfo () . В Windows порядок, в котором ОС разрешает адреса, вероятно, определяется чем-то вроде этого , в то время как в Linux приоритет разрешения определяется
/etc/nsswitch.conf
DNS сервер , используя протокол UDP, реагирует на клиента с записью / IP - адрес, если он существует
Клиент открывает соединение TCP на порт 80 веб - сервера и записывает следующий текст:
HTTP-запрос:
Вы можете повторить то же самое, выполнив что-то подобное в консоли или командной строке:
следуют две пустые строки. Если запрошенный контент существует, веб-сервер распечатает его на экране. Если с другой стороны есть браузер, текст ответа анализируется браузером, и все теги, ссылки, сценарии и изображения отображаются на так называемой веб-странице.
В действительности есть еще несколько деталей, например, браузеры могут кэшировать IP-адреса, если вы уже посетили какой-либо домен, поэтому разрешение DNS становится ненужным. Кроме того, современные браузеры могут попытаться выполнить разрешение до того, как оно действительно понадобится ( предварительная выборка DNS ) для ускорения просмотра.
Кроме того, на вашем компьютере могут быть статические записи в
hosts
файле. Если запись соответствует запросу, сначала используется локальная статическая запись, и ни один DNS-сервер никогда не связывался. Это настраивается, и не обязательно верно, но это по умолчанию в операционных системах, с которыми я знаком.источник
GET http://www.pippo.it/hello.htm HTTP/1.1
будет действительный, если необычный, запрос. Это также будет действительный и обычный запрос к HTTP-прокси.gethostbyname()
несколько устарел. Можно было бы лучше использоватьgetaddrinfo()
...HTTP передается через TCP, который является протоколом IP. Чтобы сделать HTTP-запрос, браузер должен открыть TCP-соединение, и для этого ему нужен IP-адрес назначения (то есть IP-адрес сервера). Чтобы разрешить имя хоста сервера, он, таким образом, должен выдать DNS-запрос (обычно сам DNS-запрос отправляется операционной системой, когда программа вызывает свои функции разрешения имен; однако ничто не мешает программе самостоятельно отправлять DNS-запросы в DNS. сервер). Как только соединение установлено, оно может отправить свой HTTP-запрос, который содержит путь к запрашиваемому ресурсу и поле Host с именем хоста сервера (например,
Host: www.pippo.it
). Имя хоста не идет в строке запроса (это было бы на самом делеGET /hello.htm HTTP/1.1
), за исключением случаев, когда запрос отправляется на HTTP-прокси (и в этом случае присутствует полный URL-адрес, включая, напримерGET http://www.pippo.it/hello.htm HTTP/1.1
, часть протокола ),источник
Процедура идет так:
http://www.pippo.it/hello.htm
Браузер разделяет это на три части:
http
www.pippo.it
/hello.htm
(более сложный URL-адрес может содержать и другие части, пока я буду игнорировать эту возможность)
Браузер знает, что для создания IP-соединения ему необходим IP-адрес. Чтобы получить IP-адрес, он должен использовать DNS (если только он не кэширован).
8.8.8.8
.Браузер создает следующее многослойное соединение:
8.8.8.8
A
записи для имени хостаwww.pippo.it
Конечно, я опускаю много деталей, например, о точном формате пакетов.
www.pippo.it
, скажем,10.11.12.13
http
во внутренней таблице и узнает, что ему следует использовать порт 80.Браузер создает следующее многослойное соединение:
10.11.12.13
Уровень HTTP: создайте запрос HTTP для URL
/hello.htm
на хостеwww.pippo.it
(поскольку на компьютере10.11.12.13
может быть размещено несколько доменов, поэтому ему необходимо знать, какой из них нужен)Конечно, я опускаю все детали TCP-рукопожатия и тому подобное.
hello.htm
И в качестве меры предосторожности я упомяну, что браузер теперь анализирует содержимое этого ответа и определяет любые дополнительные ресурсы, необходимые: изображения, CSS, Javascript и т. Д. Затем он повторяет весь этот процесс для каждого такого ресурса.
источник
getaddrinfo
илиgethostbyname
просит ОС разрешить адрес для него. Кроме того, ОС обычно использует несколько механизмов для поиска имен, а не только DNS. (Как правило, по крайней мере, файл hosts в дополнение к DNS.)