Próbuję zrozumieć protokoły warstwy aplikacji w stosie TCP / IP. Wiem, że zarówno protokół HTTP, jak i DNS pozostają na górnej warstwie (Warstwa aplikacji). Tak więc, gdy przeglądarka chce uzyskać dostęp do zasobu, musi wysłać żądanie do serwera HTTP, na przykład:
GET www.pippo.it/hello.htm HTTP/1.1
Wysyłając to żądanie zgodnie z regułami protokołu HTTP, używa adresu URL strony, a nie adresu IP.
Wiem, że żądanie DNS jest konieczne do konwersji adresu URL na adres IP. Moje pytanie brzmi: czy HTTP wywołuje protokół DNS? Wydaje mi się to niemożliwe, ponieważ oba są protokołami najwyższej warstwy (więc DNS nie może zapewnić usługi HTTP). W ten sam sposób nawet TCP (który pozostaje na niższym poziomie) nie może poprosić o usługę na protokole wyższego poziomu, takim jak DNS.
Kiedy więc pojawia się żądanie DNS? A kto wykonuje takie żądanie?
źródło
Odpowiedzi:
Żądanie HTTP, o którym mowa, jest w rzeczywistości nieprawidłowe, chyba że przeglądarka rozmawia z pośrednikiem (proxy).
Twój przykład wyglądałby bardziej jak poniżej, gdyby przeglądarka bezpośrednio komunikowała się z serwerem sieciowym:
Teraz, aby spojrzeć na to z perspektywy, rozważ model OSI:
W akcji mamy 3 systemy:
Stosowane protokoły są od dołu do góry (minimalny odpowiedni zestaw do PO):
Komunikacja HTTP odbywa się za pośrednictwem protokołu TCP (TCP znajduje się nad protokołem IP), podczas gdy komunikacja DNS w tym przypadku odbywa się za pośrednictwem protokołu UDP (UDP jest również nad protokołem IP).
Oto sekwencja komunikacji w skrócie:
Klienta , uruchamiając przeglądarkę, zwraca się do serwera DNS za
A
rekordwww.pippo.it
, przy użyciu protokołu UDP.1.1 Na kliencie jest to system operacyjny, który wykonuje część rozstrzygającą i odsyła do przeglądarki --- przeglądarka nigdy nie komunikuje się bezpośrednio z serwerem DNS, raczej poprzez system operacyjny, wywołując gethostbyname () lub nowszą getaddrinfo () . W systemie Windows, kolejność, w jakiej OS rozwiązuje adresy prawdopodobne jest zdefiniowany przez coś takiego jak ten , podczas gdy w systemie Linux pierwszeństwo rozwiązywaniu jest zdefiniowana przez
/etc/nsswitch.conf
Serwer DNS , korzystając z protokołu UDP, odpowiada klientowi za pomocą rekordu / adresu IP, jeśli istnieje
Klient otwiera połączenie TCP na porcie 80 na serwerze WWW i zapisuje się następujący tekst:
Żądanie HTTP:
Możesz naśladować to samo, robiąc coś takiego w konsoli lub wierszu polecenia:
a następnie dwie puste linie. Jeśli żądana treść istnieje, serwer internetowy wydrukuje ją na ekranie. Jeśli po drugiej stronie znajduje się przeglądarka, tekst odpowiedzi jest analizowany przez przeglądarkę, a wszystkie tagi, łącza, skrypty i obrazy są renderowane na tak zwanej stronie internetowej.
W rzeczywistości istnieje kilka dodatkowych szczegółów, np. Przeglądarki mogą buforować adresy IP, jeśli już odwiedziłeś jakąś domenę, więc rozpoznawanie DNS staje się zbędne. Ponadto nowoczesne przeglądarki mogą próbować rozwiązać problem, zanim rzeczywiście go potrzebujesz ( pobieranie DNS ), aby przyspieszyć przeglądanie.
Ponadto komputer może zawierać statyczne rekordy w
hosts
pliku. Jeśli rekord pasuje do żądania, lokalny wpis statyczny jest wykorzystywany jako pierwszy i nigdy nie kontaktuje się z żadnym serwerem DNS. Jest to konfigurowalne i niekoniecznie prawdziwe, ale jest domyślne w systemach operacyjnych, które znam.źródło
GET http://www.pippo.it/hello.htm HTTP/1.1
Byłoby to zatem ważne, jeśli nietypowe, żądanie. Byłoby to również prawidłowe i zwykłe żądanie do serwera proxy HTTP.gethostbyname()
jest nieco przestarzały. Lepiej byłoby użyćgetaddrinfo()
...HTTP jest przesyłany przez TCP, który jest protokołem IP. Aby złożyć żądanie HTTP, przeglądarka musi otworzyć połączenie TCP, a do tego potrzebuje docelowego adresu IP (tj. Adresu IP serwera). Aby rozwiązać nazwę hosta serwera, musi on zatem wysłać żądanie DNS (zazwyczaj samo żądanie DNS jest wysyłane przez system operacyjny, gdy program wywołuje funkcje rozpoznawania nazw; jednak nic nie stoi na przeszkodzie, aby program sam wysyłał żądania DNS do DNS serwer). Po ustanowieniu połączenia może wysłać żądanie HTTP, które zawiera ścieżkę do żądanego zasobu oraz pole Host z nazwą hosta serwera (np
Host: www.pippo.it
.). Nazwa hosta ma nie iść na linii żądania (to faktycznie byćGET /hello.htm HTTP/1.1
), z wyjątkiem sytuacji, gdy żądanie jest wysyłane do serwera proxy HTTP (w tym przypadku obecny jest pełny adres URL, w tym część protokołu, np.GET http://www.pippo.it/hello.htm HTTP/1.1
),źródło
Procedura wygląda następująco:
http://www.pippo.it/hello.htm
Przeglądarka dzieli to na trzy części:
http
www.pippo.it
/hello.htm
(bardziej skomplikowany adres URL może również zawierać inne części, na razie zignoruję tę możliwość)
Przeglądarka wie, że aby utworzyć połączenie IP, potrzebuje adresu IP. Aby uzyskać adres IP, musi używać DNS (chyba że ma buforowany adres).
8.8.8.8
.Przeglądarka tworzy następujące połączenie wielowarstwowe:
8.8.8.8
A
rekordu dla nazwy hostawww.pippo.it
Oczywiście pomijam wiele szczegółów na temat np. Dokładnego formatu zaangażowanych pakietów.
www.pippo.it
, powiedzmy, że to10.11.12.13
http
w swojej wewnętrznej tabeli i dowiaduje się, że powinien używać portu 80.Przeglądarka tworzy następujące połączenie wielowarstwowe:
10.11.12.13
Warstwa HTTP: utwórz żądanie HTTP dotyczące adresu URL
/hello.htm
na hościewww.pippo.it
(ponieważ komputer10.11.12.13
może być hostem dla wielu domen, więc musi wiedzieć, która jest pożądana)Oczywiście pomijam wszystkie szczegóły uzgadniania TCP i tym podobne.
hello.htm
Na wszelki wypadek wspomnę, że przeglądarka analizuje teraz treść tej odpowiedzi i identyfikuje wszelkie dodatkowe potrzebne zasoby: obrazy, CSS, JavaScript itp. Następnie powtarza ten cały proces dla każdego takiego zasobu.
źródło
getaddrinfo
lubgethostbyname
prosi system operacyjny o rozpoznanie adresu. Ponadto system operacyjny zwykle używa wielu mechanizmów do wyszukiwania nazw, nie tylko DNS. (Zazwyczaj przynajmniej plik hosta oprócz DNS.)