前言当我们在浏览器中输入网址时会发生什么?你有没有想过这背后发生了什么神奇的事情?今天丹丹,我就来一层层揭开浏览器背后的故事。.本文将从如何生成HTTP报文开始,然后介绍DNS服务器如何帮助我们查询IP地址,最后介绍协议栈最终是如何发送报文的。文章很长,大家忍住。一、生成HTTP请求报文1、解析URLURL,其实应该叫URL。一般URL以“http://”开头,但也有以“ftp://”、“file://”等开头的URL。这部分文字表示浏览器使用的访问方式。访问Web服务器时,使用HTTP协议,访问FTP服务器时,使用FTP协议。整个URL除了一开始需要指定的协议方法外,还包括服务器的域名和要访问的文件的路径名等,如下图所示:让我们使用以HTTP协议为例进行说明:www.lab.glasscom.com表示要访问的服务器地址,后面的路径名/dir/file1.html表示访问该路径下的file1.html文件服务器。有的朋友可能会有一些疑惑。在日常生活中,有时我们访问的网站地址并没有指定具体要访问的文件名,而只是一个简单的域名。在这种情况下,大多数服务器会设置一个默认的访问路径,例如是index.html还是default.htm等。这是浏览器工作的第一步,解析URL。2、HTTP的基本工作原理通过分析URL,我们已经知道访问的目的地在哪里,然后浏览器就会通过HTTP协议访问Web服务器。HTTP协议是一个非常重要的知识点,后面我会专门开一个专栏来详细讲解。这里我简单介绍一下,让大家有个思路。HTTP协议定义了客户端与服务器交互的消息内容和步骤。如上图所示,客户端会向服务器发送请求消息。请求可以有不同的操作。HTTP通过方法表达不同的操作:Web服务器收到请求后,完成自己的处理,并将处理结果存储在response消息中,response消息会回传给客户端,然后客户端读取结果并显示出来。3、HTTP请求报文的生成HTTP请求报文是有格式要求的,所以浏览器会按照指定的格式生成请求报文。请求行:请求消息的第一行称为请求行。三个重要的参数,请求方法,告诉服务器做什么;URL:指定要访问的服务器地址和路径,最后是协议版本,HTTP协议有不同的版本,需要标明HTTP版本号。请求头:请求头用来放置一些额外的细节,比如客户端支持的数据类型、语言、压缩格式、日期等。消息体:这里存放你需要发送的数据。下面我就举个真实的例子给大家一探究竟。比如我们访问www.baidu.com,第一行就是请求行。从请求行可以看出是GET请求,访问路径为/,协议版本为1.1。第一行往下是请求头,因为没有数据要发送,所以没有请求体。4.收到请求报文后,响应报文的格式与请求报文大致相同,只是第一行不同。响应消息的第一行是请求协议、状态码和响应短语,用于表示请求的执行结果是成功还是错误。二、如何查询IP地址1、IP地址基础知识生成HTTP报文后,我们会通过操作系统将报文发送到您的Web服务器。在通过操作系统发送消息之前,还有一件重要的事情要做,就是查询域名对应的IP地址。Internet中的局域网是基于TCP/IP设计的。网络是由一些小的子网用路由器连接起来形成一个大网络。在网络中,所有的设备都会分配一个地址,就像你住的地方,叫做“XX房间XX”,这个号码分配给整个子网,房间分配给子网内的电脑,整个称为IP地址。发送方发送的报文会先通过子网的集线器转发到距离最近的路由器,然后路由器再根据目的地址发送到下一个路由器,重复这个过程,最终到达目的地。2、为什么要共享域名和IP地址?首先,应该提出两个问题。我们先想一想:我们可以直接通过IP地址来判断目标地址。为什么我们需要使用域名?能不能直接用域名来确定访问对象呢?回答第一个问题,IP地址是一串数字,但是想想实际情况,如果每次访问网站都输入IP地址,估计很难记住,但是用名字好记多了,好记多了。解决。下面说说第二个问题,用域名直接判断访问对象,绕过IP,从实际运行效率上来说是行不通的。IP地址的长度是4个字节,最短的域名也需要几十个字节,越长,路由器处理数据的时间就越长。路由器的速度是有限的。在目前的现实中,路由器的性能已经接近饱和,直接访问是行不通的。什么是最好的方法?是吗?让人用名字,让路由器用IP地址,谁来建立域名和IP地址的关系呢?网桥是DNS。3、如何查询IP地址我们可以通过DNS服务器查询到IP地址。我们的电脑会有一个DNS客户端向DNS服务器发起请求。我们称之为DNS解析器。通过DNS查询IP地址的操作就是域名解析。三、DNS服务器详解1.DNS服务器的基本工作流程它的基本工作是接收客户端的查询报文,然后根据报文的内容返回响应信息。一般来说,客户端的查询报文会包含三部分:域名:服务器的名称。Class:Class的值始终为IN,代表Internet。记录类型:表示域名对应的类型。如果类型为A,则表示该域名对应一个IP地址;如果类型为MX,则表示该域名对应一个邮件服务器。DNS服务器会从域名和IP地址对照表中查找对应的记录并返回。2、如何根据域名结构快速查找域名目前域名数量庞大,不可能全部放在一台DNS服务器中,所以信息会分散存储在多个DNS中服务器,这些DNS服务器将相互协作以搜索出最终结果。DNS中的域名以点号分隔,如www.lab.glasscom.com,根据公司的组织结构,com代表集团,glasscom代表业务部门,lab代表集团。层次结构中的部分称为域。一个域的信息会整体存储在DNS服务器中,一台服务器可以存储多个域的信息。我们如何找出我们要访问的服务器的信息属于哪个DNS服务器呢?首先,我们可以将负责管理下级域名的DNS服务器的IP地址注册到其上级DNS服务器上,然后再将上级DNS服务器的IP地址注册到上级DNS服务器上,很快。这样做有什么好处?如果我们要查询www.lab.glasscom.com,那么我们可以通过com域的DNS服务器找到保存glasscom.com域的DNS服务器,一直往下走,最后就可以找到对应的IP地址到所需的域名。现实生活中,有一台保存根域的服务器。什么是根域?它是一个比com.它一般不会在域名中体现出来,但却是真实存在的。它管理着所有下级DNS服务器的信息,全球只有13个根域服务器的IP地址。这些地址不会改变,所以所有的DNS服务器都会存储这13个IP地址。我们来看看如何找到目标DNS服务器。客户端会先访问最近的DNS服务器,然后因为最近的DNS服务器没有保存我们需要的域名对应的IP地址,所以我们需要从最上层往下看,通过根域服务器,直到找到目标DNS服务器获取我们需要的IP地址。一般来说,如果是我们经常查询的域名信息,DNS服务器本身是有缓存功能的,会记录你之前查询过的域名,这样当你请求的域名信息在缓存中时,DNS服务器会直接返回响应,省去了每次都从根域中查找的麻烦,减少了查询时间。四、委托协议栈发送报文1、数据收发过程当我们通过DNS服务器获取到需要的IP地址后,就可以让操作系统内部的协议栈向目标IP发送报文。发送和接收数据是通过使用Socket库来完成的,如下图所示:在发送和接收数据之前,客户端和服务端首先要建立一个管道。这个管道的关键是管道的数据进出,我们称之为socketCharacter。所以我们需要先创建一个socket,然后才能建立管道。服务器首先会创建一个套接字,客户端也会创建一个套接字,然后连接到服务器。当发送数据时,将断开与管道的连接,通信擦除操作将结束。我们将这个过程分为4个阶段:创建套接字。将管道连接到服务器套接字。发送和接收数据。断开管道并删除套接字。2.创建套接字套接字是如何创建的?其实就是调用了Socket库中的socket组件。创建后,协议栈会返回一个描述符。程序接收这个描述符并将其存储在内存中。这个描述符是用来标识不同的socket的,因为浏览器可能有多个请求,那么就会创建多个socket,所以必须要有一个flag来标识。比如当你入住酒店,多人同时入住时,为了保证你入住的是不同的房间,每个人都会发一张房卡作为唯一标识,方便服务员查找根据房卡对应的人。3.如何连接pipesocket创建好后,我们需要和server连接。这里我们调用Socket库中的connect组件来完成。要调用连接组件,我们需要传递三个参数:描述符、服务器IP地址和端口号。.前两个参数大家都已经知道了。这个端口号的作用是什么?试想一下,IP地址可以让我们找到对应的服务器,但是服务器可能部署了多个应用,比如部署了两个web服务。我们简单的根据IP是无法识别的,所以我们还需要加上端口号才能找到具体的服务。可能有人会说,我们不是有一个描述符吗,只有这个?这是行不通的,因为服务器不知道这个描述符。4.发送消息和收发数据最后发送消息很简单,就是给socket发送数据,会发送到对方的socket。这个过程也是通过Socket库的编写程序组件完成的。消息返回后,接收消息是通过Socket库中的read组件完成的。服务器发送响应消息后,会通过调用close组件主动执行断开连接操作。当客户端接收完数据后,也会调用close断开连接。总结当浏览器输入URL时,浏览器首先会解析URL,然后我们会生成一个HTTP请求报文,介绍一下HTTP协议的基本概念。因为我们是通过域名访问的,所以需要通过DNS获取目标访问对象的IP地址,最后我们介绍了使用协议栈(TCPIP)来真正向服务端发送消息,完成数据的接收。一个URL请求背后涉及到很多方面的知识。只有知道它是什么,知道为什么,才能真正学到更多有价值的知识。
