HTTP GET方法如何与DNS协议相关?

我想了解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请求实际上是无效的,除非浏览器正在与中介(代理)通话。

如果浏览器直接与Web服务器通话,那么您的示例看起来会更像下面的内容:

 GET /hello.htm HTTP/1.1 Host: www.pippo.it 

现在来看看OSI层模型

在这里输入图像描述

所以我们有3个系统在行动。

  • 运行浏览器的客户端
  • 网站服务器Web服务器
  • 知道该网站的IP地址的DNS服务器

涉及的协议是; 自下而上(最小相关设置为OP)

  • IP
  • TCP,UDP
  • HTTP,DNS

HTTP通信是通过TCP协议完成的,而TCP通信是在IP协议之上的

这种情况下的DNS是通过UDP协议完成的,UDP协议是在IP协议之上的。

沟通顺序简而言之:

  1. 运行浏览器的CLIENT请求使用UDP协议的DNS服务器loggingwww.pippo.it

    1.1。 客户端是parsing部分和浏览器交谈的操作系统,浏览器永远不会直接与DNS通话,而是通过调用gethostbyname()或更新的getaddrinfo()来通过操作系统。 在Windows中,操作系统parsing地址的顺序可能由类似这样的东西来定义,而在Linux上,parsing优先级由/etc/nsswitch.conf

  2. DNS服务器使用UDP协议响应客户端与logging/ IP地址(如果存在)

  3. CLIENT打开TCP连接到WEB服务器的 80端口,并写入以下文本

HTTP请求:

 GET /hello.htm HTTP/1.1 Host: www.pippo.it 

你可以通过在console / cmd提示符下做类似的事情来模拟相同的事情

 > telnet www.pippo.it 80 Trying 195.128.235.49... Connected to www.pippo.it. Escape character is '^]'. GET /hello.htm HTTP/1.1 Host: www.pippo.it 

跟着两条空行。 这个Web服务器会响应,如果请求的内容存在,它将打印到屏幕上,而在浏览器的情况下,这个hypertext实际上被浏览器parsing,所有的标签,链接,脚本和图像被渲染成我们所说的网页。

实际上还有一些细节,例如浏览器cachingIP地址,如果你已经访问了某个域,那么DNSparsing可能不是必须的。 此外,现代浏览器可能会尝试在实际需要( DNS预取 )之前进行parsing,以加快浏览体验。

另外,您的计算机可能在主机文件中有静态logging,并且不会接触任何DNS服务器,而是首先使用本地静态条目。 这是可configuration的,但不一定是正确的,但它是我熟悉的主要操作系统的默认值。

HTTP是通过TCP(一种IP协议)传输的。 为了发出HTTP请求,浏览器必须打开一个TCP连接,并做到这一点,它需要目标IP地址(即服务器的IP地址)。 要parsing服务器的主机名,就必须发出一个DNS请求(一般来说,DNS请求本身是在程序调用其名称parsing函数时由操作系统发送的;但是,没有什么能阻止程序自己发送DNS请求到DNS服务器)。 build立连接后,它可以发送包含所请求资源path的HTTP请求,以及具有服务器主机名的主机字段(例如Host: www.pippo.it )。 主机名不在请求行上(实际上是GET /hello.htm HTTP/1.1 ),除非请求发送给HTTP代理(在这种情况下,包含协议部分,例如GET http://www.pippo.it/hello.htm HTTP/1.1 ),

程序是这样的:

  1. 用户(你)给浏览器一个URL,比如http://www.pippo.it/hello.htm
  2. 浏览器将其分为三部分:

    • 协议http
    • 主机名www.pippo.it
    • urlpath/hello.htm

    (一个更复杂的URL也可能有其他部分,我现在会忽略这种可能性)

  3. 浏览器知道为了创build一个IP连接,它需要一个IP地址。 要获得一个IP地址,它需要使用DNS(除非它有地址caching)。

    1. 浏览器向操作系统询问DNS服务器的IP地址; 假设它得到8.8.8.8
    2. 浏览器构build以下多层连接:

      • IP层:连接到8.8.8.8
      • UDP层:为目标端口53设置数据包
      • DNS层:为主机www.pippo.itAlogging创build一个DNS请求

      当然,我省略了很多关于包的确切格式的细节。

    3. 浏览器收到一个DNS响应(在IP层上面分层的UDP层),给出www.pippo.it的IP地址,假设是10.11.12.13
  4. 浏览器知道为了创build一个TCP连接,它需要一个端口号。 为了获得一个端口号,它在内部表中查找协议http ,并获知它应该使用端口80。
  5. 浏览器构build以下多层连接:

    • IP层:连接到10.11.12.13
    • TCP层:将数据包设置为目标端口80
    • HTTP层:为主机/hello.htm上的URL /hello.htm创build一个HTTP请求(因为计算机在10.11.12.13可能需要托pipe多个域,所以需要知道哪一个是需要的)

       GET /hello.htm HTTP/1.1 Host: www.pippo.it ... 

    当然,我省略了TCP握手等的所有细节。

  6. 浏览器接收包含hello.htm内容的HTTP响应(层叠在IP层顶部的TCP层上)

为了更好的衡量,我会提到浏览器现在检查响应的内容,并确定所需的额外资源:图像,CSS,Javascript等等。然后对每个这样的资源重复整个过程。