Featured image of post 网络是怎样连接的 01 - 浏览器与HTTP

网络是怎样连接的 01 - 浏览器与HTTP

探索浏览器内部

通过与浏览器进行简单的交互,学习网络相关的基础知识点。

整体预览

通过浏览器生成 HTTP 请求消息

我们要做的第一步就是在浏览器中输入网址,如https://azusachino.icu/p/understand-network-browser-http/。其中网址整体被称作 URL,而azusachino.icu/之后的内容叫做 URI。

  • URL (Uniform Resource Locator)
  • URI (Uniform Resource Identifier)

解析 URL

浏览器的第一步工作就是对 URL 进行解析,从而生成发送给 Web 服务器的请求消息。

浏览器支持的协议多种多样,如 httpftpfilemailto 等,当然在日常生活中 httphttps 用的比较多。

组装 HTTP 请求

在解析完 URL 之后,浏览器就会向目标服务器发送 HTTP 请求了。其中,HTTP 协议定义了客户端和服务端之间交互的消息内容和步骤。

  1. 客户端向服务端发送请求消息,其内容用 REST 的思想来说就是:针对某个资源进行某种操作的描述。
  2. 服务端在收到请求消息之后,会根据描述执行相应的操作,然后将结果存放在响应消息中。

HTTP 请求/响应消息示例

请求和响应中有非常多的 Header 信息,这里就不方便展示了,可以借一步查询官方文档

HTTP 方法清单

通过 DNS 服务器查询 Web 服务器的 IP 地址

当然,在 HTTP 请求真正发送到网络之前,浏览器还需要向 DNS 服务器查询目标地址的 真实 IP,毕竟是 TCP/IP 嘛。

IP 地址 (IPv4)

一般来说,IP 地址就像是邮政地址一样,收发方都是唯一的,这样才能保证邮件能够到达指定地点。

当然有部分 IP 是可以重复的,比如经常在 docker 中看到的 172.16.0.0/12,毕竟 IPv4 的地址已经不够用了,不过重复的 IP 就不能在公网使用了。

通过 Socket 库获取查询 IP 能力

简单展示 gethostbyname 的使用方式。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>
#include <netdb.h>

int main(int argc, char *argv[])
{
    struct hostent *lh = gethostbyname("azusachino.icu");
    if (lh)
        puts(lh->h_name);
    else
        herror("gethostbyname");

    return 0;
}

DNS 解析流程示例

DNS 服务器的层层接力

委托协议栈发送消息

  1. 创建套接字
  2. 将管道连接到服务器端的套接字上
  3. 收发数据
  4. 断开管道并删除套接字

总结

一味地抄书,我好菜。

Reference

The older I get, the more I realize that most of life is a matter of what we pay attention to, of what we attend to [with focus].
Built with Hugo
Theme Stack designed by Jimmy