Gia*_*rlo 19 domain-name-system tcpip http
我正在尝试了解 TCP/IP 堆栈中的应用层协议。我知道 HTTP 和 DNS 协议都停留在顶层(应用层)。因此,当浏览器想要访问资源时,它必须向 HTTP 服务器发送请求,例如:
GET www.pippo.it/hello.htm HTTP/1.1
Run Code Online (Sandbox Code Playgroud)
这个请求遵循 HTTP 协议的规则,它使用页面 URL,而不是 IP 地址。
我知道将 URL 转换为 IP 需要 DNS 请求。所以我的问题是:HTTP 会调用 DNS 协议吗?这对我来说似乎是不可能的,因为两者都是顶层协议(因此 DNS 无法为 HTTP 提供服务)。以同样的方式,即使 TCP(停留在较低级别)也无法在更高级别的协议(如 DNS)上请求服务。
那么DNS请求什么时候发生呢?谁执行了这样的请求?
Hrv*_*jar 40
有问题的 HTTP 请求实际上是无效的,除非浏览器正在与中介(代理)交谈。
如果浏览器直接与 Web 服务器通信,您的示例看起来更像以下内容:
GET /hello.htm HTTP/1.1
Host: www.pippo.it
Run Code Online (Sandbox Code Playgroud)
现在,为了正确看待这一点,请考虑 OSI 模型:

我们有 3 个系统在运行:
所涉及的协议是,从下到上(最小相关设置为 OP):
HTTP 通信通过 TCP 协议完成(TCP 位于 IP 协议之上),而 DNS 通信在这种情况下通过 UDP 协议完成(UDP 也位于 IP 协议之上)。
简而言之,通信顺序如下:
运行浏览器的客户端使用 UDP 协议向DNS 服务器请求A记录www.pippo.it。
1.1. 在客户端,由操作系统完成解析部分并与浏览器对话——浏览器从不直接与 DNS 服务器对话,而是通过操作系统调用gethostbyname()或较新的getaddrinfo()。在Windows上,其中OS解析地址的顺序由像很可能定义这个,而在Linux上解决优先级被定义/etc/nsswitch.conf
该DNS服务器,使用UDP协议,来响应客户端用一记/ IP地址(如果存在)
在客户端打开的端口80上的TCP连接的Web服务器,并写入以下内容:
HTTP请求:
GET /hello.htm HTTP/1.1
Host: www.pippo.it
Run Code Online (Sandbox Code Playgroud)
您可以通过在控制台或命令提示符中执行以下操作来模拟相同的事情:
> 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
Run Code Online (Sandbox Code Playgroud)
后跟两个空行。如果请求的内容存在,Web 服务器会将其打印在屏幕上。如果另一端有浏览器,则浏览器会解析响应文本,并且所有标签、链接、脚本和图像都在我们所谓的网页中呈现。
实际上还有更多的细节,例如,如果您已经访问过某个域,浏览器可能会缓存 IP 地址,这样 DNS 解析就变得不必要了。此外,现代浏览器可能会尝试在您实际需要之前进行解析(DNS 预取)以加快浏览速度。
此外,您的计算机可能在hosts文件中有静态记录。如果记录与请求匹配,则首先使用本地静态条目,并且不会联系任何 DNS 服务器。这是可配置的,不一定是真的,但它是我熟悉的操作系统的默认设置。
Ale*_*Ale 14
HTTP 通过 TCP 传输,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浏览器将其分为三个部分:
httpwww.pippo.it/hello.htm(更复杂的 URL 也可能有其他部分,我暂时忽略这种可能性)
浏览器知道为了创建 IP 连接,它需要一个 IP 地址。要获得 IP 地址,它需要使用 DNS(除非它缓存了地址)。
8.8.8.8.浏览器构建如下多层连接:
8.8.8.8A为主机名的记录创建 DNS 请求www.pippo.it当然,我省略了很多细节,例如所涉及的数据包的确切格式。
www.pippo.it,假设它是10.11.12.13http在其内部表中查找协议,并得知它应该使用端口 80。浏览器构建如下多层连接:
10.11.12.13HTTP 层:为/hello.htm主机上的 URL 创建一个 HTTP 请求www.pippo.it(因为 at 的计算机10.11.12.13可能托管多个域,因此需要知道需要哪个)
GET /hello.htm HTTP/1.1
Host: www.pippo.it
...
Run Code Online (Sandbox Code Playgroud)当然,我省略了 TCP 握手等的所有细节。
hello.htm为了更好地衡量,我会提到浏览器现在检查该响应的内容,并确定所需的任何其他资源:图像、CSS、Javascript 等。然后它对每个这样的资源重复整个过程。