问题: 网络模型的层次结构是怎么样的? 为什么要分层?


为了方便管理以及简化网络的复杂度, 网络的不同方面被分解成多层次结构,每一层只与相邻的上层或下层进行通信,这样做的意义会通过解耦大大的降低网络的复杂度.

主流的分层模型结构有两种:

  • OSI 开放系统互联参考模型

    OSI开放系统互联参考模型
    应用层
    表示层
    会话层
    传输层
    网络层
    数据链路层
    物理层
  • TCP/IP 协议族模型

    TCP/IP 协议族模型
    应用层
    传输层
    网络层
    数据链路层
    物理层

问题: Http请求一个 www.baidu.com 的网络模型结构是怎样的一个结构?


Http请求 主要分为两步. 第一步获取目标服务器的IP地址; 第二步通过http协议获取相应的内容.

  • 获取目标服务器的IP地址主要是通过DNS请求来获取的,整体示意图如下所示.

    • 首先是浏览器缓存查找,通过查找浏览器的DNS缓存,确认缓存的有效性之后,如果没有则继续.

    • 浏览器DNS缓存如果查找不到,那就查找本地的host配置文件,查看是否有该DNS配置,如果没有则继续.

    • 本地host文件查找不到,则会在应用层创建一个DNS请求报文.

    • 在传输层,由于DNS请求报文是依赖于UDP协议的,所以会添加UDP协议请求头.

    • 在网络层,同样会在UDP请求报文的基础上添加IP的请求头.

    • 在数据链路层,首先会通过一个局域网二层寻址找到下一个设备的Mac地址.(通过网络层ARP协议获取到下一个目标设备Mac地址.) 并且把当前设备的MAC地址头和需要发送到下一个设备的MAC地址头添加到请求报文中.

    • 通过物理层发送到下一个设备(路由器).

    • 路由器一个三层结构的设备,首先通过物理层接受到DNS请求报文.

    • DNS请求报文上传到路由器的数据链路层,数据链路层会判断当前报文的目标MAC地址是否自身,如果不是自身,那么就会舍弃该报文,如果报文的目标MAC地址是自身,那么会进行解析,并且传输到路由器的网络层,网络层依然会通过ARP协议请求来获取下一个目标设备的MAC地址,继续网线传输.

    • 当DNS请求报文发送到网络运营商这边时,网络运营商就会根据DNS请求报文中的IP地址确认当前DNS服务器是否是当前运营商的DNS解析服务器,如果是,则会发送该DNS请求报文,如果不是,那么会通过网络发送给其他的DNS服务器.

    • 最终 DNS解析服务器会收到DNS请求报文,然后最终获得目标服务器的IP地址,然后原来返回到设备上.


  • 当拿到目标服务器的IP地址后,则会进行HTTP请求报文发送,整体过程如下图所示.

    • 在拿到通过DNS解析拿到目标地址的IP地址之后,会在应用层构建一个HTTP请求报文.

    • HTTP请求报文会在传输层添加TCP相关参数,添加TCP请求头.

    • 在网络层,则依然会添加到IP头.

    • 在数据链路层,则会通过二层寻址找到需要传输的下一个目标设备的MAC地址.

    • 通过光纤等物理设备发送到局域网的路由器上.

    • 请求报文上传到路由器的数据链路层,数据链路层会判断当前报文的目标MAC地址是否自身,如果不是自身,那么就会舍弃该报文,如果报文的目标MAC地址是自身,那么会进行解析,并且传输到路由器的网络层,网络层依然会通过ARP协议请求来获取下一个目标设备的MAC地址,继续网线传输.

    • 后面通过运营商、专线等传输最终通过IP地址找到目标服务器.

    • 目标服务器会通过网络链路层判断当前HTTP请求报文是否是发送给自己,如果是,则会进行接收.

    • 接收的HTTP请求报文会顺着网络层级结构往上传输,当到了应用层的时候,会根据对应的端口来找到对应的应用程序,然后把请求报文发送给该程序.

    • 目标程序处理完HTTP请求报文后,则会创建相应报文,相应报文会按照原来返回传输给源设备.


问题: 简述一下Http报文的结构?


HTTP 1.1 协议下,报文结构如下图所示.

  • 起始行

    请求行报文格式如图所示,主要包含一下结构.

    • METHOD: 请求方式,例如GET/PUT/POST/DELETE,表示对资源的操作;

    • URL: 请求目标,通常是一个URL,标记了请求方法要操作的资源;

    • VERSION: 表示请求报文使用的HTTP协议版本号.

    响应行报文格式如图所示,主要包含一下结构.

    • VERSION: 表示响应报文使用的HTTP协议版本号.

    • STATUS CODE: 状态码,一个三位数的数字来表示处理的结果状态.例如200表示成功,404表示未找到,500表示服务器异常.

    • REASON: 作为状态码的原因补充,可便于理解状态码的详细内容.


  • HTTP 头部字段

    头部字段是以 key-value 形式存在的,两者之间是以 : 进行分割的,最后用 CRLF 换行表示字段结束.头部字段不但可以使用标准定义好的key,也可以自定义相关key-value进行传输.


  • 消息正文

    不管是请求报文还是相应报文,都是可以添加消息正文的.


问题: 简述一下Http请求的完整过程?


整体的Http请求过程如下图所示.

  • 首先就是获取目标服务器的IP地址,这一步会先查看本地浏览器的DNS缓存记录,再去查看本地host配置文件中的配置.如果上述两者都没有任何缓存记录,那么久会发起一个DNS请求,通过DNS服务器获取到目标服务器的IP地址.

  • 有了目标服务器的IP之后就会发起TCP的三次握手,如果是Https请求,还会发起TLS握手.

  • 当与目标服务器建立连接之后,Client端就会发起HTTP请求,目标服务器做出响应.

  • 通过解析Http响应报文中得消息正文,渲染页面.

  • 最后通过TCP的四次挥手断开连接.


问题: 简述一下TCP和UDP的特点?


  • TCP

    TCP是面向连接,可靠的,基于字节流的传输层协议.

    特点:

    • 面向连接: 通过三次握手建立可靠的连接.

    • 仅支持单播传输: 每条TCP传输连接只有两个端点,只能进行点对点数据传输,不能实现组播和广播.

    • 面向字节流: 不限制数据大小,不保留报文边界的情况下以字节流进行数据传输.

    • 可靠传输: 对于可靠传输.判断误码和丢包主要是通过TCP 字节流数据包的编号以及确认号.TCP为了保证报文传输的可靠,会在每一个字节流数据包一个序号,同时序号也保证了传送到接收端可以有序的接收,每一个数据包接收完成都要接收端都要发送一个(ACK)确认数据包. 如果发送端在往返时延(RTT)未收到确认数据包,那么发送端需要重发该数据包.

    • 拥塞控制: 当网络出现拥塞的情况下, TCP通过算法可以减少往网络注入数据的数量和速率,缓解拥堵.

  • UDP

    UDP 是无连接的,不可靠,基于报文的传输层协议.

    特点:

    • 面向无连接: 在传输过程中,如果是通过UDP协议,那么在报文只会添加上UDP标识头.不会进行任何操作.

    • 支持单播、组播、广播: UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。

    • 面向报文: 对于从应用层传输下来的报文,UDP既不会分割也不会合并,朱慧添加上UDP标识头.并且保留报文的边界,这时候就需要应用程序自己控制报文的大小.

    • 不可靠性: 首先是无连接,通信都不需要建立连接.想什么时候发送数据就什么时候,非常不可靠; 其次,并且传输数据过程中是不会备份数据,也不关心接收端是否已经接收到数据,所以是不可靠的.

    • 头部开销很小,传输效率很高: UDP头部数据为8bits, TCP为20bits-60bits.基本上不改变整体的数据结构,传输效率较高.


问题: 简述一下TCP的三次握手和四次挥手的过程?


要了解三次握手和四次挥手就要先了解TCP的头部数据结构.在应用层传输报文到传输层时,TCP会添加如下的报文信息.

  • TCP的三次握手

    TCP三次握手过程整体过程如下所示.

    • Client 会发送一个标识位为SYN的请求报文, seq序号的值为随机生成的值 x. 并且进入 SYN-SENT 状态.

    • Server 接收到SYN请求报文的时候,它会保存相关的报文的内容信息,并且会发送两个报文,一个是确认报文 ACK, ack的值为 x + 1,另外一个则是SYN报文, seq的值为随机生成的 y,两个报文可能合并为一个报文发送(减少传输数据的成本).这时服务器进入 SYN-RECEIVED 状态.

    • Client接收到确认报文的时候就会进入 ESTABLISHED 状态,并且会发送一个ack确认报文,报文中ack的值为 y + 1

    • Server 接收到ack报文之后也会进入 ESTABLISHED 状态.

  • TCP的四次挥手

    TCP四次挥手过程整体过程如下所示.

    • 不管是Client还是Server都可以主动发起 close 关闭操作.

    • 例如Client发起 close 关闭操作时, 会向服务端发送一个 FIN (seq序号为随机值 x) 关闭报文. Client进入 FIN_WAIT_1 状态.

    • 服务器接收到FIN关闭报文时,会发送一个 ACK确认报文(ack为 x+1 ).并且开始处理收尾工作.

    • Client接收到ACK确认报文之后, 会进入 FIN_WAIT_2 状态,等待Server收尾工作的结束.

    • Server把所有的收尾工作做完之后,开始发起服务器 close 关闭操作. 往Client发送一个 FIN关闭报文(seq序号为随机值 y),表示Server要关闭TCP连接通道.

    • Client接收到Server的 FIN关闭报文时,会往Server发送一个 ACK确认报文(ack为 y+1 ),此时并不会真正关闭连接,而是进入 TIME_WAIT 状态.

    • Server当收到 ACK报文之后就会真正关闭TCP连接.

    • Client在2MSL时间周期之后会真正关闭TCP连接.

    注:

    1. close 关闭操作一旦执行之后,当前设备就不会在发送业务数据了.
    2. TIME_WAIT 状态的主要作用是当ack报文发送失败,由于TCP的机制,Server会重发FIN报文,如果没有TIME_WAIT状态(Client释放了TCP连接),那么Client对于重发的FIN 报文永远没有处理时机,进而导致Server的资源不能被释放掉,造成浪费.

问题: TCP的滑动窗口协议和累计确认(ACK确认)?


滑动窗口协议(Sliding Window Protocol),属于TCP协议的一种应用,用于网络数据传输时的流量控制,以避免拥塞的发生。该协议允许发送方在停止并等待确认前发送多个数据分组。由于发送方不必每发一个分组就停下来等待确认。因此该协议可以加速数据的传输,提高网络吞吐量。


问题: 简述一下HTTPS的加密通道如何建立?


HTTPS的加密通道建立主要是通过 TLS 来进行实现的, TLS是采用混合加密方式也就是对称加密和非对称加密.HTTPS通道建立过程如下图所示.

整体流程如下所示.

  • 首先,Server 会创建公钥与私钥,公钥可以传输,但是私钥只会保存到服务器上.

  • HTTPS和正常的HTTP连接一样,会通过TCP的三次握手与服务器建立连接.

  • Client端会往服务端发送自己支持的加密算法套件.

  • 服务端选择合适的加密算法套件和公钥数字证书一起发给Client端.

  • Client端拿到公钥之后,与自身生成的对称加密秘钥Key生成 对称秘钥密文.

  • Client发送对称秘钥密文到服务端,服务端通过私钥进行解密,获得对称加密秘钥Key.

  • 至此,Client和Server双方都获得了对称加密的秘钥,然后数据传输使用此秘钥进行加密与解密.


问: 为什么不都用非对称加密?而是采用混合加密方式?

答: 非对称加密虽然保密性更高,但是性能不高.所以采用混合加密方式.


问题: 简述一下HTTPS1.0 HTTP1.1 HTTP2.0 之间的差异?


参考资料

  • HTTP1.0和HTTP1.1的区别

    • 长连接(Persistent Connection)

      HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务器端要建立一个长连接。

    • 节约带宽

      HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器;如果返回401,客户端就可以不用发送请求body了节约了带宽。

    • HOST域

      在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误(400 Bad Request)。

    • 缓存处理

      在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

    • 错误通知的管理

      在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

  • HTTP1.1和HTTP2.0的区别

    • 多路复用

      HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。

    • 头部数据压缩

      在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent、Cookie这类不会频繁变动的内容,完全是一种浪费。

      HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。

    • 服务器推送

      服务端推送是一种在客户端请求之前发送数据的机制。网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP1.1中这些资源每一个都必须明确地请求。这是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。

      为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。


IT界无底坑洞栋主 欢迎加Q骚扰:676758285