网联:第一章:浏览器生成消息

1.概述:

下面是我画的一张思维导图,作为概述:

 

2.生成http请求:

url有不同的种类,例如常见的http,ftp,mailto,不同的协议标识着他们用于不同的功能,也可以把他们看作一种url功能上的分类.不同的分类有遵守着各自的规则.也就是我们所说的协议.

2-1:那浏览器是如何解析url地址的:

url地址是一个字符串,解析的时候会根据特定的字符去拆分,其中"//" 作为一个分隔标识,他前面的标识协议,后面是服务器的名称,服务器后面的 "/",标识文件路径.有的路径在服务上不存在,如果nginx会出找相应的应用路由匹配,如果存在文件路径,会被当做文件路径使用.

 

2-2: http的基本思路:

 

 图中的1:请求信息包括两部分: 对什么,进行什么操作.

其中"对什么"指的是内容,指的是资源路径,成为URI(uniform resource identifier).如具体的某一个html,一张图片 xxx.com/abc.html,  xxx.com/abc.jpg

也可以把uri理解为邮件上的地址,完成一次通信,不是只有地址就可以的,还需要邮差去送,走着送还是骑车,还是火车,这就是请求的方式,也就是"进行什么操作"

常见的请求方式:GET,POST.OPTION HEAD,PUT,DELETE等.客户端在发送数据前会先发送头字段.在发送数据.

图中2,web服务器接收到消息后,根据要求作出响应,并将响应结果放到响应信息里,其中有一个状态码用于标识成功还是失败.

 

2-3:生成http请求:

根据uri资源的路径和请求的方式根据协议规定生成请求信息:

第一行: 请求行.告诉服务他该进行什么样的操作.

请求行的第一个单词告诉我们请求的方式,也就是我们使用的浏览器打算用什么方式去访问资源

请求方式后面隔一个空格是uri,

最后一个是http的版本.

 

第二行 消息头:

格式是:<字段名>:<字段值>

消息头可以附加额外的信息,详情.

 

消息头结束后需要一个空白行做标识.用于区分消息头结束了.

消息体:需要发送的数据,也就是消息的主体.

因为在日常使用get方式进行请求的时候,仅凭方法和uri,服务器就知道要进行怎样的操作.所以大多时候不需要在消息体重填写东西.但当使用form表单进行提交的时候,数据就会放到消息体中.

 

2-4:请求消息的响应:

上面提到了请求信息,及请求信息头的结构.下面是对请求信息的响应做出的回应.

响应头和请求头相似,不同的是响应头,响应头的第一行是状态码和响应短语.

下面是常见的状态码:

 

 

 

3.向DNS服务器查询web服务器的ip

生成http的请求消息后,接下来需要委托操作系统将消息发送给web服务器,尽管浏览器可以解析并生成http消息,但是本身不具备将消息发送到网络中的功能.需要委托操作系统来完成.但是操作系统在发送请求的时候,请求的地址必须时具体的ip,所以在这之前需要将域名转化成ip,也就是想dns

3.1 ip的基础知识:

ip其实是一串32位的比特字符串,八比特一组,分四组,并用圆点分隔,并将每一组的二进制转换为十进制表示.这也就是为什么ip字段中最大的值255了,因为8位二进制能表示的最大的数为11111111,转换成十进制为255.

互联网中有大大小小无数的子网,不同的子网通过网络号进行区分,而同一子网下的不同机器的区分,是通过主机号来区分的.而类似127.0.0.1这种形式的ip,是将网络号和主机号组合在一起的,这两部分是不固定的,可以在组件网络的时候自行配置.网络号主机号连在一起32位的形式.所以需要附加信息来进行区分,这个附加信息是子网掩码

子网掩码是一串与ip类似的32位的比特数字,他的值和ip的值(二进制的值)是一一对应的,1表示网络号,0表示主机号.

 

产生的疑问:好多局域网内人的子网掩码都是一致的都是255.255.255.0.这个怎么区分不同的主机?

主机号和网络号的两种特别的含义,全0表示整个子网,全1表示向网络上所有的设备发送包,也就是广播.下面是几种掩码的表示

 

 

对于dns服务器,我们的电脑上一定有dns的客户端,而这个客户端就是dns解析器,通过dns查询ip地址的操作称为域名解析,解析器就是一段代码,他存在于操作系统的socket库中,那什么是socket库?socket库的程序组件可以让程序调用操作系统的网络功能,而解析器就是这个socket库中的一个组件或者说是一段程序.

 

4.dns服务大接力:

dns服务器的工作流程: 接收来自客户端的查询消息,根据消息内容进行响应. 来自客户端的内容包含三方面的内容:

域名:服务器,邮件服务器的名称

记录类型:标识域名对应何种类型的记录.如A标识的是ip地址,mx标识的是邮件,不同的类型记录,dns服务器返回的信息格式也是不相同的.

Class: 早期的设计方案中通过class标识互联网以外的网络,但是目前只有互联网,所以class永远标识互联网的IN

示例:查询www.baidu.com的ip

浏览器会将请求转发给dns解析器,解析器里面准备以下内容:

a) 域名: www.baidu.com

b)CLASS: IN

c) 记录类型:A

响应结果: 61.135.169.125

 

寻找响应的dns服务器并获取ip:

互联网中有数万台dns服务器,不能一台一台的去找相应的服务器,下面是解决方案:将负责管理下级域名的服务器ip注册到更上一级的dns服务器中,如此类推

举例:lab,glass.com这个域名的服务器会把服务器ip注册到glass.com这个dns服务器上,而glass.com又会吧服务器ip注册到com这个服务器上.这样我们从右往左就可以确定这个域名所对应的服务器的ip了.

通过缓存增加dns的访问速度: dns有缓存功能会记住曾经访问过的域名对应的域名的服务器信息,这样避免从根域名开始查找.

 


5.委托栈发送消息: 通过上述的操作获取到了用户的ip,然后应用就可以委托操作系统内部的协议栈向目标ip发送消息了.下面是操作的过程:

 

 

获取目标地址的ip以后浏览器就要委托操作系统发送信息了.
下面是主要的流程:
1.客户端创建套接字
2,将管道连接到服务器端的套接字上.
3.通过管道收发数据
4.断开管道并删除数据(断开管道,客户单和服务端都可以主动断开)
 
以上的四个操作都是在操作系统的协议栈中进行的.浏览器等应用并不会自己去创建管道,都需要委托协议栈.(如何委托和创建管道在第二章)
 
创建套接字阶段:
客户端创建套接字非常简单只要客户端调用socket库中的组件就可以了,套集字创建好以后协议栈会返回给浏览器一个文件描述符,应用程序会将文件描述符fd,存到内存中,用于去人不同的socket套接字,
 
 
连接阶段: 客户端建立和服务端的socket连接管道
协议栈在创建完socket客户端后,会调用socket库里面的connect组件,建立管道,connect需要以下的参数
connect(文件描述符,目标socket的ip,端口号)
 
通信阶段: 传递消息
创建socket套接字并通过管道连接到服务端后,就可以开始讲数据传递金套接字了,这个操作同样是需要socket库来UI协议栈进行操作,这个需要write组件,具体过程如下:
首先应用程序会将要发送的数据存进内存里,这个要发送的数据是根据用户的操作,浏览器对请求进行封装的请求数据,随后浏览器或者应用调用socket库的write组件,委托操作系统发送数据.
 
断开连接: 收发数据结束
当浏览器收到数据以后,也就意味着本次连接结束,socket库会调用close组件关闭连接.
根据web使用的http规范,web服务器发送完响应应该主动断开连接.所以服务器会主动断开连接,然后客户端也会进入close阶段.接下来浏览器调用socket库的read方法时,read告诉浏览器连接已经结束,浏览器得知以后也会进入close阶段.
在http1.1以前是一个连接满足一个请求,一个页面多张图片怎需要多次连接有多少张图片就发起多少次连接,http1.1后才可以一次连接进行多次请求和响应,当所有的请求都完成以后才会结束调用close.
 
 
 
 
 
 
 
 
 
 

 

posted @ 2020-01-02 23:39  callmelx  阅读(205)  评论(0编辑  收藏  举报