《网络是怎样连接的》相对比较简单,易理解(虽然我觉得干货也不少),整本书以浏览器发送请求出发,经过一系列过程最终达到服务器的过程为主线,具体如下。

alt

  • 第一章 web浏览器

输入网址URL解析开始,到浏览器将数据委托给协议栈发送为止。关键词:浏览器、web服务器、网址(URL)、HTTP、HTML、协议、URI、请求消息、解析器、Socket库、DNS服务器、域名。

第一章 web浏览器

本章节流程:生成HTTP请求消息->向DNS服务器查询web服务器IP地址->DNS服务器接力->委托协议栈发送消息。

生成HTTP请求消息

输入网址(URL)

URL:Uniform Resource Locator 统一资源定位符。如https://blog.nowcoder.net/detail/0, 可以是http,https,ftp等,通常包含协议(访问方法更准确,比如使用file做开头的URL不使用网络),域名,服务器文件路径,有时会有一些请求信息和端口号。

浏览器解析URL

c中URL经过Web浏览器解析后知道访问的是服务器dir1目录下的file1.html文件。

alt

省略文件名的情况

当只有目录名+'/'的情况,默认执行该目录下的default.html或者index.html文件,如果'/'都没有,则匹配文件名/目录名,注意是不可能存在相同名称(包括拓展名的完整名字)的文件和目录的。

HTTP的基本思路

解析完URL使用HTTP协议访问Web服务器。

alt

HTTP 协议定义了客户端和服务器之间交互的消息内容和步骤。首先,客户端会向服务器发送请求消息。请求消息中包含的内容是“对什么”和“进行怎样的操作”两个部分。

  • 相当于“对什么”的部分称为 URI(Uniform Resource Identifier,统一资源标识符),URI的内容通常是一个存放网页数据的文件名或者是一个CGI程序的文件名,例如“/dir1/file1.html”“/dir1/program1.cgi”。
  • 相当于“进行怎样的操作”的部分称为方法。方法表示需要让 Web 服务器完成怎样的工作,常见的有Post,Get。

alt

客户端生成HTTP请求消息 && 收到服务端响应消息

  • 请求消息由请求行、消息头、消息体组成,请求行最重要,包含方法,URI,HTTP版本,对于Get方法的请求消息没有消息体,因为不需要添任何数据。

alt

Post和Get类的请求消息的实例如下:

alt

  • 响应消息由状态行、消息头,消息体组成,状态行中的状态码是给程序看的,响应短语是给人看的,表示请求的执行结果是成功还是出错。

alt

返回响应消息后,浏览器将数据取出显示,如果数据中有图片等资源,则会再次发送请求获取。具体来说,浏览器会在显示文字时搜索相应的标签,当遇到图片相关的标签时,会在屏幕上留出用来显示图片的空间,然后再次访问Web 服务器,按照标签中指定的文件名向 Web 服务器请求获取相应的图片并显示在预留的空间中。由于每条请求消息中只能写 1 个 URI,所以每次只能获取 1 个文件,如果需要获取多个文件,必须对每个文件单独发送 1 条请求。1个网站有三张图片,则需要发送4条请求给服务器。

向DNS服务器查询服务器IP地址

IP地址的格式如下,注意主机号全0表示子网,全1表示广播。

alt

域名是IP地址的别称,易记。DNS解析器(客户端)通过向DNS服务器查询将域名解析成IP地址,其本质是Socket库中的程序,通过gethostbyname调用,具体向DNS服务器发送查询请求通过协议栈,和向web服务器发送请求的思路是一样的,DNS服务器的IP地址已经预先被配置好(配置DNS实际就是在配置最近DNS服务器的IP地址)。

alt

DNS服务器接力

DNS客户端的查询消息包含域名,Class(固定互联网IN),记录类型。DNS服务器的基本工作就是根据需要查询的域名和记录类型查找相关的记录,并向客户端返回响应消息。

alt

域名的层次结构和分布式存储使得DNS查询能够高效进行,总结如下图。

alt

自上向下查询,客户端首先向配置的DNS服务器查询,找不到再去问根域,根域再一级一级向下分发查询,在这一过程中,如果有DNS缓存记录,则可以直接返回对应的查询IP地址。

委托协议栈发送消息

请求消息准备好后,也查到了服务器对应的IP地址,下一步委托操作系统内部的协议栈向这个目标IP地址发送消息。这里以TCP协议来举例说明收发数据的过程。

alt

套接字是数据的出入口,是一个抽象的概念,实体表现为ip地址+端口号和描述符。

  • 描述符:应用程序用来识别套接字的机制。
  • IP 地址和端口号:客户端和服务器之间用来识别对方套接字的机制。

这么说其实挺抽象的,结合协议栈收发数据的过程更好理解。

alt

整个过程分为创建套接字,连接,发送/接受,断开。创建套接字就是指定一个标识符作为传输通道入口的名字,这个名字只在客户端这一头可知,那服务端怎么知道返回消息的时候客户端传输口在哪呢,所以还需要通过IP地址和端口号来指定,反过来对客户端也是一样的。在连接过程中,客户端和服务端的套接字存储了彼此的IP地址和端口号,这样就知道该发给谁了。发送时,应用程序通过标识符找到套接字,在根据套接字存的IP地址和端口号找到服务器的套接字,连接建立就可以发送数据了。接收时,数据会先进入响应消息的接受缓冲区,通过socket库的read程序读取,进入缓冲区相当于数据已经到达客户端。最后断开连接,哪一方先close都有可能。具体协议栈工作过程会在下一节进行介绍。

之前说过,文字和图片是分开的单独的一次请求,对应就要建立一次连接,在HTTP版本1.1以上,开始支持一次连接中收发多个请求和响应的方法。