计网分层思想
下面通过一个常见的网络应用实例来介绍计算机网络体系结构的分层处理方法。
如下图,主机属于网络 N1,Web服务器属于网络 N2, N1 和 N2 通过路由器互联,用户通过主机 N1 使用浏览器访问 Web 服务器的过程如下:
- 用户通过主机,在浏览器的地址中输入Web服务器的域名 (*step1 所示)
- 主机 向 Web服务器发送一个请求报文 (*step2 所示)
- Web服务器接收到请求后,执行相应的操作,然后给主机发送响应报文 (*step3 所示)
- 主机收到响应报文后,由浏览器负责解析和渲染显示
注意: 上述网络应用实例仅给出了一个简化的示意过程,本文的重点是计算机网络体系结构的分层处理方法,而不是浏览器和 Web服务器的详细交互过程。
主机和 Web服务器之间基于网络的通信,实际是主机中的浏览器应用进程与 Web服务器中的 Web服务器应用进程之间基于网络的通信。
1. 主机对数据包的处理过程
主机对数据包的处理过程如下图所示
应用层:
根据 HTTP 协议的规定,构建一个 HTTP 请求报文,用来请求 Web服务器执行相应的操作。
应用层将构建好的 HTTP 请求报文向下交付给运输层。
运输层:
给 HTTP 请求报文添加一个 TCP 首部,将其封装成 TCP 报文。
TCP 首部的主要作用是区分应用进程和实现可靠传输。
运输层将封装好的 TCP 报文段向下交付给网络层。
网络层:
为 TCP 报文添加一个 IP 首部,将其封装成 IP 数据报。
IP 首部的主要作用是 IP 寻址和路由。
网络层将封装好的 IP 数据报向下交付给数据链路层
数据链路层:
为 IP 数据报添加一个首部和一个尾部,将其封装成帧。
帧首部和尾部的主要作用是 MAC 寻址和帧校验
数据链路层将封装好的帧向下交付给物理层
物理层:
物理层并不认识帧的结构,仅仅将其看做比特流,以便将比特流转换成相应的电信号进行发送。
对于以太网,物理层还会在比特流前添加前导码,目的是使接收方的时钟同步,并做好接收准备。
主机方将电信号发送出去
2. 路由器对数据包的处理过程
路由器收到数据包后对其进行处理和转发的过程如下
物理层(接收口):
收到的电信号转换成比特流,并去前导码
将帧向上交付给数据链路层
数据链路层(接收口):
去掉帧的首部和尾部
将 IP 数据报向上交付给网络层
网路层:
网络层从 IP 数据报的首部中提取出目的 IP 地址
根据目的 IP 地址查找自己的转发表,以便决定从哪个接口转发该 IP 数据报
与此同时,对首部中的某些字段值(例如生存时间 TTL 字段的值)进行相应的修改
将该 IP 数据报向下交付给数据链路层
数据链路层(转发口):
为 IP 数据报添加一个首部和一个尾部,将其封装成帧
将帧向下交付给物理层
物理层(转发口):
- 将帧看做比特流,给其添加前导码后转变成相应的电信号发送出去
3. Web服务器对数据包的处理过程
Web 服务器收到数据包后,按网络体系结构自下而上的顺序对其进行逐层解封,解封出 HTTP 请求报文。
4. Web 服务器给主机发送HTTP响应报文的过程
Web 服务器的应用层收到 HTTP 请求报文后执行相应的操作,然后给主机发送包含有浏览器请求内容的 HTTP 响应报文。
与浏览器发送 HTTP 请求报文的过程类型,HTTP 响应报文需要再 Web服务器层层封装后才能发送,
数据包经过路由器的转发到达主机,主机对收到的数据包按照网络体系结构自下而上的顺序逐层解封,解析出 HTTP 相应报文。
5. 从输入 URL 到页面显示完整的流程
用户输入URL,浏览器会根据用户输入的信息判断是搜索还是网址。
如果是搜索内容,就将搜索内容+默认搜索引擎合成新的URL;
如果用户输入的内容符合URL规则,浏览器就会根据URL协议,在这段内容上加上协议合成合法的URL
用户输入完内容,按下回车键,浏览器导航栏显示loading状态,但是页面还是呈现前一个页面,这是因为新页面的响应数据还没有获得
浏览器进程浏览器构建请求行信息,会通过进程间通信(IPC)将URL请求发送给网络进程 GET /index.html HTTP1.1
网络进程获取到URL,先去本地缓存中查找是否有缓存文件,如果有,拦截请求,直接200返回;否则,进入网络请求过程
网络进程请求DNS返回域名对应的IP和端口号,如果之前DNS数据缓存服务缓存过当前域名信息,就会直接返回缓存信息;否则,发起请求获取根据域名解析出来的IP和端口号,如果没有端口号,http默认80,https默认443。如果是https请求,还需要建立TLS连接。
Chrome 有个机制,同一个域名同时最多只能建立 6 个TCP 连接,如果在同一个域名下同时有 10 个请求发生,那么其中 4 个请求会进入排队等待状态,直至进行中的请求完成。如果当前请求数量少于6个,会直接建立TCP连接。
进行TCP三次握手建立连接,http请求加上TCP头部——包括源端口号、目的程序端口号和用于校验数据完整性的序号,向下传输
网络层在数据包上加上IP头部——包括源IP地址和目的IP地址,继续向下传输到底层
底层通过物理网络传输给目的服务器主机
目的服务器主机网络层接收到数据包,解析出IP头部,识别出数据部分,将解开的数据包向上传输到传输层
目的服务器主机传输层获取到数据包,解析出TCP头部,识别端口,将解开的数据包向上传输到应用层
应用层HTTP解析请求头和请求体
如果需要重定向,HTTP直接返回HTTP响应数据的状态 code 301 或者 302,同时在请求头的Location 字段中附上重定向地址,浏览器会根据 code 和 Location 进行重定向操作;
如果不是重定向,首先服务器会根据请求头中的 If-None-Match 的值来判断请求的资源是否被更新
如果没有更新,就返回 304 状态码,相当于告诉浏览器之前的缓存还可以使用,就不返回新数据了;
否则返回新数据,200的状态码,并且如果想要浏览器缓存数据的话,就在相应头中加入字段:Cache-Control:Max-age=2000
响应数据顺着应用层—>传输层—>网络层—>网络层—>传输层—>应用层的顺序返回到网络进程
数据传输完成,TCP四次挥手断开连接。如果,浏览器或者服务器在HTTP头部加上
Connection:Keep-Alive
,TCP就一直保持连接 (保持TCP连接可以省下下次需要建立连接的时间,提示资源加载速度)网络进程将获取到的数据包进行解析,根据响应头中的Content-type来判断响应数据的类型
如果是字节流类型,就将该请求交给下载管理器,该导航流程结束,不再进行;
如果是text/html类型,就通知浏览器进程获取到文档准备渲染
浏览器进程获取到通知,根据当前页面B是否是从页面A打开的并且和页面A是否是同一个站点(根域名和协议一样就被认为是同一个站点)
如果满足上述条件,就复用之前网页的进程
否则新创建一个单独的渲染进程
浏览器会发出“提交文档”的消息给渲染进程,渲染进程收到消息后,会和网络进程建立传输数据的“管道”,文档数据传输完成后,渲染进程会返回“确认提交”的消息给浏览器进程
浏览器收到“确认提交”的消息后,会更新浏览器的页面状态,包括了安全状态、地址栏的 URL、前进后退的历史状态,并更新web页面,此时的web页面是空白页
渲染进程对文档进行页面解析和子资源加载,HTML 通过HTM 解析器转成DOM Tree(二叉树类似结构的东西),CSS按照CSS 规则和CSS解释器转成CSSOM TREE,两个tree结合,形成render tree(不包含HTML的具体元素和元素要画的具体位置),通过Layout可以计算出每个元素具体的宽高颜色位置,结合起来,开始绘制,最后显示在屏幕中新页面显示出来。