第一章 浏览器生成消息
- 本章讲的是HTTP消息长啥样、往哪里发消息、怎么发消息
1.1 生成HTTP消息
- 主要讲的是HTTP消息长啥样。
HTTP是啥?
- Hypertext Transfer Protocol,超文本传送协议。
URL是啥?
- Uniform Resource Locator,统一资源定位符。
- URL常见格式?

- Web浏览器解析URL的过程?

几种省略文件名的情况:
HTTP的基本思路:

HTTP消息主要包含两个部分:“对什么”和“进行怎样的操作”。其中,“对什么”的部分称为Uniform Resource Identifier,统一资源标识符。“进行怎样的操作”的部分称为方法。
- HTTP的主要方法:

- HTTP请求消息到底长啥样?
- 第一行称为请求行。这里表明了请求方法以及HTTP的版本行。
- 第二行为消息头。这里表明了如日期、客户端支持的数据类型、语言、压缩格式、客户端和服务器的软件名称和版本、数据有效期和最后更新时间等。
- 第三行为空行。
- 最后一部分为消息体。

- HTTP响应消息到底长啥样?
- 第一行为状态码和响应短语,二者表示内容一致,即成功或失败。状态码是一个数字,响应短语是一段文字。
- 第二行为空行。
- 最后一部分为消息体。

注意:1 条请求消息中只能写 1 个 URI。如果需要获取多个文件,必须对每个文件单独发送 1 条请求。
一个浏览器与Web服务器进行消息交互的实例:



1.2 向 DNS 服务器查询 Web 服务器的 IP 地址
主要讲的是向哪里发消息。
TCP/IP的结构:
- 路由器:一种对包进行转发的设备
集线器:一种对包进行转发的设备
子网:用集线器连起来的几台计算机
- 网络:用路由器把子网连起来
- IP地址:某一台计算机在网络中的地址

- 先简单看一下消息发送的具体过程:
- 发送者发出的消息经过子网的集线器,发到最近的路由器上。
- 路由器会根据消息的目的地判断下一个路由器的位置,然后将消息发送到下一个路由器上。
- 第二步不断重复,消息就到了目的地。
- IP地址的组成:
- 本质是一串32比特的数字,按照8比特也就是1字节为一组分成4组。
- 4组数字分别用十进制表示,再用圆点隔开。
- 在32比特中,包括了网络号和主机号。因此还需要额外的信息来表明哪一部分是网络号,哪一部分是主机号。
- 子网掩码用于表明网络号和主机号的组成形式
- 子网掩码中为1的部分代表网络号,为0的部分代表主机号,如下图b
- 或者表明左数多少个比特是网络号,如下图c
- IP地址的主机号全0表示整个子网,全1表示向子网上的所有设备发送包,即广播。


- 为什么有了域名还要IP?
- 因为IP只要处理32比特的地址,而域名往往更长,处理地址的时间更长。
- 那为啥不干脆直接用IP?
- IP太难记,偷懒记个域名比较方便。
- DNS是啥?
- Domain Name System,域名服务系统。
对于DNS服务器,计算机上有相应的DNS客户端。这个客户端就叫做DNS解析器或者解析器,通过DNS查询IP地址的操作就叫域名解析。负责执行解析这一操作的就是解析器。
解析器实际上是一段程序,存在于OS的Socket库中。Socket 库是用于调用网络功能的程序组件集合。
- 如何才能知道域名和IP地址的对应关系?
- 问问最近的DNS服务器就知道了。

- 解析器内部原理:

- Btw,向DNS服务发消息的时候当然也要知道DNS服务器的IP。不过这个IP是提前设置好的,如windows中:

1.3 全世界 DNS 服务器的大接力
- 主要讲的还是往哪里发消息
- DNS服务器接收来自客户端的消息,包含以下三种:
- 域名
- Class:早期设计DNS时,考虑了除互联网以外的其他网络,Class用于识别网络类型,互联网的Class值为IN。
- 记录类型:表示域名是何种类型的记录。比如当类型为A(Address)代表域名对应的是IP地址,当类型为MX(Mail eXchange)时,表示域名对应的时邮件服务器。
- DNS工作流程:

- 域名的层次结构:
在域名中,越靠右的位置表示层级越高。其中,相当与一个层级的部分称为域。比如www.lab.glasscom.com 这个域名,公有4个域,www、lab、glasscom、com,其中com层级最高,www最低。每个域的信息作为整体存放在DNS服务器中,一台DNS服务器可以保存多个域的信息。简单起见,我们默认一台DNS服务器只保存一个域的信息。
- 域名千千万,DNS服务器千千万,如何知道我们想找的域名对应的Web服务器的信息在哪一台DNS服务器上?
- 首先,将下级域的DNS服务器的IP地址注册到它们的上级DNS服务器中。
- 再将上级DNS服务器的IP地址注册到更上级,以此类推形成树状结构。
- 这样就就可以按照层级结构,从高到低查询IP。
- 一般来说,com等域貌似是顶级域了,但其实在com之类的域之上还有一级域,称为根域,通常被省略。如果不省略就加一个点,如 www.lab.glasscom.com. 。
- 首先将根域的IP地址保存到所有DNS服务器中,这样每一台DNS服务器可以从根域开始向下搜索,找到一个域名对应的IP。
- 分配给根域服务器的IP地址全世界只有13个。(虽然IP地址只有13个,但是服务器是非常多的)

- 具体查询域名对应IP地址的流程如下:

- DNS服务器存在缓存功能,如果之前查过的,可以直接返回。但是注意,原本注册的信息可能发生改变,所以DNS服务器应该给缓存设置有效期。并且,DNS响应查询时,应该告诉客户端响应结果是来自缓存还是查出来的。
1.4 委托协议栈发送消息
- 主要讲的是怎么发消息。
- 使用TCP协议来收发数据的过程如下图:
- 创建套接字(创建套接字阶段)
- 将管道连接到服务器端的套接字上(连接阶段)
- 收发数据(通信阶段)
- 断开管道并删除套接字(断开阶段)

- 在发送数据前,两台计算机之间应当建立管道。管道两端的数据出入口称为套接字。
- 首先,服务器端创建套接字,然后客户端创建套接字,最后套接字连接形成管道。
1.4.1 创建套接字阶段
- 只需要调用Socket库中的socket程序组件即可。调用后返回一个描述符用于识别不同套接字。
1.4.2 连接阶段:把管道接上去
- 调用Socket库中connect组件,须传入三个参数:
- 描述符,即表明用哪一个套接字和服务器端的套接字连接
- IP
- 端口号
1.4.3 通信阶段:传递消息
- 发送消息,调用Socket库中的write程序组件,传入两个参数:
- 描述符
- 发送数据
- 接收消息,调用Socket库中的read程序组件,传入两个参数
- 描述符
- 保存响应消息的内存地址。
1.4.4 断开阶段:收发数据结束
- 调用Socket库中的close程序组件,传入一个参数,描述符。
1.4.5 一图胜千言
