HolyZheng / holyZheng-blog

草稿
36 stars 0 forks source link

计算机网络相关 #9

Open HolyZheng opened 6 years ago

HolyZheng commented 6 years ago

ps:物理层,数据链路层,网络层(IP),运输层(UDP、TCP),应用层(http) url构成

从在浏览器输入url开始,发送了什么?

1. 进行DNS解析

dns解析就是一个从域名找到对应ip的过程

  1. 查看浏览器缓存
  2. 查看系统缓存,查看本地hosts文件,查看是否有对应ip
  3. 查询路由器缓存和ISP缓存
  4. 查询本地DNS服务器
  5. 查询域名服务器 (分级查询:根域服务器 -》 顶级域名服务器 -》主域名服务器)

    2. TCP连接(传输层协议)

    拿到ip后,开始进行tcp连接(三次握手,四次挥手)

    三次握手

    通俗解释

  6. 客户端向服务器询问是否可以连接
  7. 如果可以,服务器回复可以连接
  8. 客户端收到后,进行回复确认

TCP首部几个信息

首部 解释
seq序列号 表示当前发送了多少数据
ack确认号 接收端通过确认号来表示接收到了多少数据
SYN 同步标识,说明本次请求用来建立连接
ACK 确认标识,接收端确认接收到数据,ACK=1时,ack才会被包含在TCP中
FIN 结束标识,说明此请求用来结束连接

为什么需要三次握手? 三次握手是为了确保双方能正常通信,防止因网络原因已失效的请求又传到了服务端而产生错误。 服务端收到失效报文后,若无“三次握手”,会认为客户端此时要建立连接但客户端并不知情。

3.http请求

建立连接后进行http请求

4. tcp连接断开,四次挥手

为什么需要四次挥手? 因为主动断开的一方已经没有数据发送了,但是被动断开的一方,收到断开请求和发送确认信息后,可能还有数据要发送,当确定没有数据要发送后,再向主动方发送断开请求,主动发收到后再发送确认信息。

5. 浏览器接收到资源,渲染页面等

  1. 根据我们的html生成一个dom树,
  2. 根据我们的css生成一个cssom树,
  3. 然后根据dom树和cssom树生成一个渲染树rendering tree。
  4. 遍历渲染树,计算每个节点的大小与位置
  5. 将每个节点渲染到屏幕上。

    ps:Load 事件触发代表页面中的 DOM,CSS,JS,图片已经全部加载完毕。 DOMContentLoaded 事件触发代表初始的 HTML 被完全加载和解析,不需要等待 CSS,JS,图片加载。

ps:重绘(Repaint)和回流(Reflow),重绘是当节点需要更改外观而不会影响布局的,比如改变 color 就叫称为重绘。回流是布局或者几何属性需要改变就称为回流。(添加或删除可见原生,改变元素的位置和尺寸,浏览器窗口尺寸改变)方法:先通过display:none隐藏元素,再修改,再显示,2次重绘和回流。添加多个元素时还可以使用文档片段(DocumentFragment)作为参数(例如,任何 Node 接口类似 Node.appendChild 和 Node.insertBefore) 的方法),这种情况下被添加(append)或被插入(inserted)的是片段的所有子节点, 而非片段本身。因为所有的节点会被一次插入到文档中,而这个操作仅发生一个重渲染的操作,而不是每个节点分别被插入到文档中,因为后者会发生多次重渲染的操作。

协议

tcp(传输控制协议)

面向连接,可靠的运输层的协议。 面向连接:在使用TCP协议之前必须建立连接。 可靠传输的原理:当出现差错时,让发送方重传出现差错的数据,在接收方来不及处理收到的数据时,及时告诉发送方适当降低发送数据的速度。

超时重传机制

①停止等待协议

(1)无差错情况 (2)出现差错,当超过重传时间还未收到确认信息时,重传分组。 a,发送方发送完后,需要保留一份已发送的分组的副本。在收到相应的确认后才能清除副本。 b.分组和确认分组都必须进行编号,以便确认分组。 c.超时计时器设置的重传时间应当比数据在分组传输的平均往返时间更长一些。 (3)“确认”丢失 当数据发送成功,但是回应的确认丢失。 发送方回重传分组,接收方收到后回删除重复分组,重发确认给发送方。 总结:发送方发送完后,需要保留一份已发送的分组的副本。在收到相应的确认后才能清除副本, 当未成功发送给接收方的时候,超过重传时间的时候会重传分组。当接收方成功接受,但是确认信号未能成功发送给发送方的时候,发送方也会重传该分组,然后接收方再删除重复分组,再发送确认信息。

②滑动窗口协议

发送方根据自己的发送窗口大小,一次性发送对应数量的分组。根据接收方的确认信息,向前移动相应多个分组位置。 接收方一般采用累计确认的方式,不必对收到的分组逐个发送确认,而是对按序到达的最后一个分组发送确认,表明在这之前的分组都正常接收了。 优点:容易实现,即使确认丢失也不必重传 缺点:不能向发送方反映已经正确收到的所有分组的信息。只能确认时前N个分组。

拥塞处理

包括了四个算法,分别为:慢开始,拥塞避免,快速重传,快速恢复

慢开始算法

慢开始算法,顾名思义,就是在传输开始时将发送窗口慢慢指数级扩大,从而避免一开始就传输大量数据导致网络拥塞。 慢开始算法步骤具体如下

  1. 连接初始设置拥塞窗口(Congestion Window) 为 1 MSS(一个分段的最大数据量)
  2. 每过一个 RTT(往返时延) 就将窗口大小乘二
  3. 为了防止拥塞窗口增长引起网络拥塞,还需要设置一个慢开始门限状态变量,当拥塞窗口大于慢开始门限状态变量的时候,会使用拥塞避免算法。

    拥塞避免算法

    拥塞避免算法相比简单点,每过一个 RTT 窗口大小只加一,这样能够避免指数级增长导致网络拥塞,慢慢将大小调整到最佳值。 在传输过程中可能定时器超时的情况,这时候 TCP 会认为网络拥塞了,会马上进行以下步骤:

  4. 将慢开始门限状态变量设置为出现拥塞时的发送窗口值得一半
  5. 将拥塞窗口设为 1 MSS
  6. 执行慢开始算法。

    快速重传

    快速重传一般和快恢复一起出现。一旦接收端收到的报文出现失序的情况,接收端只会回复最后一个顺序正确的报文序号。如果收到三个重复的 ACK,立即重传丢失分组,并执行快恢复算法。

    快恢复

  7. 当收到三个重复的ACK后,把慢开始门限状态变量减半,这是为了预防网络拥塞的出现。
  8. 然后把拥塞窗口设置为慢开始门限减半后的值,然后执行拥塞避免算法。(因为此时很可能还没出现网络拥塞,因为出现网络拥塞的话,接收方不太可能连续发送重复确认信号)

    三次握手和四次挥手

    UDP 用户数据协议

    无连接,缺乏可靠性的运输层协议 无连接:不需要先建立连接,减少开销 缺乏可靠性:不保证数据数据会到达最终目的地,不保证先后顺序,不保证数据不重复。

    HTTP 超文本传输协议

    http协议基于tcp/ip协议,是应用层的协议,http协议是无状态,无连接的,明文传输。

    • 无连接:每次链接只处理一个请求,服务器处理完客户请求后即断开连接。(以节省传输时间)
    • 无状态:对事物处理没有记忆能力,当后续的处理需要前面信息的时候,需要对需要的信息重发,数据量增大,另一面,当不需要前面信息的时候,应答较块。

      ①请求

      请求由请求行,请求头,空行,请求数据四部分

      ②响应

      响应由状态行,消息头,空行,响应正文四部分

      ③请求方法

      GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE

方法 解释
GET 请求指定页面信息,返回实体主体
HEAD 类似get请求,但是返回的响应中没有具体内容,用于获取报头
POST 向指定资源提交数据进行处理,数据保存在请求体中,它会导致新的资源的建立或已有资源的修改
PUT 从客户端向服务端传输的数据取代指定的内容
DELETE 请求服务器删除指定资源
OPTIONS 允许客户端查看服务器性能
TRACE 回显服务器收到的请求,主要用于测试或诊断
CONNECT 预留给能够将连接改为管道方式的代理服务器

post和get的差别

字段 解释
Allow 服务器支持哪些请求方法(如GET,POST)
Content-Encoding 文档的编码方法
Content-length 表示内容的长度
Content-type 表示文档属于什么MIME类型
Date 当前的GMT时间,可以用setDateHeader来设置这个头以避免转换时间格式的麻烦
Expires 表示文档过期时间,从而不缓存它
Last-Modified 文档最后改动时间,客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。
Set-Cookie 设置和页面关联的Cookie

请求头和响应头

⑥状态码

200,301,404,500. 状态码

https协议

https, 全称Hyper Text Transfer Protocol Secure(超文本传输安全协议),比http多了一个TLS(SSL)层,https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。此外客户端可以验证服务器端的身份,如果配置了客户端验证,服务器方也可以验证客户端的身份。

角色:ca机构(证书授权中心)服务器 客户端

  1. 服务器会将自己的公钥,域名等信息发送给CA机构,CA机构会用自己的私钥加密生成证书返回给服务 器
  2. 客户端发起https请求,将它支持的加密算法和一个随机数发送给服务器,服务器把证书和一个随机数和要使用的加密方法返回给客户端
  3. 客户端用本本地电脑系统中预装的对应CA机构的公钥,将证书解密。验证信息,拿到服务器公钥。
  4. 客户端生成随机数,用拿到的服务器公钥加密,发送给服务器,服务器解密,拿到随机数。
  5. 双方都有三个随机数,并确定了加密算法,于是用双方确定的加密算法和三个随机数生成一个对话密钥
  6. 此次会话就用此密钥进行对称加密。

①对称加密

在加密和解密时使用相同得密钥,或是两个可以简单互推得密钥。

例如DES, SDES, AES, IDEA, RC5, RC6

②非对称加密

具有私钥和公钥,公开出去得密钥叫做公钥,不公开得叫私钥,公钥加密的信息只有对应的私钥能解密

例如 SSL, TLS, HTTPS ps: CA证书,ca机构私钥加密的“个人信息等”,浏览器上具有对应的公钥。

HolyZheng commented 6 years ago

两种常用的用户认证方式

session-cookie机制

  1. 首先服务器会建立一张表,这里简单的叫session表
  2. 当用户登录时,服务器查用户表判断用户是否合法
  3. 如果用户认证通过,就会将用户的一些信息存放到session表中,如账号、密码之类的,同时将一个Session ID返回给客户端,这个ID是唯一的,通过这个ID就可以查找session表中对应的信息
  4. 客户端将获得的ID存到Cookie中,在下次请求时,将Cookie中的ID带到请求中
  5. 服务器收到客户端发送的请求,获得其中的Session ID,通过Session ID来查找Session表,获得用户的信息,并验证用户的身份。

    问题

  6. Session机制是服务端的机制,每次用户认证都要查Session表或者在Session表增添记录,当用户量比较大时,会给服务器带来比较大的压力,而且通常来讲,Session表都是保存到内存中,这样可以加快搜索速度,但是用户基数太大,服务端的内存开销就会很大
  7. 扩展性比较差,如果Session表保存到内存中,那么用户认证成功后,下次请求必须还是这台服务器做响应,降低了分布式服务集群的优势,扩展性差
  8. 前面也提了,hacker拿到了Cookie中唯一的Session ID依旧可以通过用户认证,虽然用过期时间,但是在这段时间内,hacker该做的也做完了

JWT(JSON WEB TOKEN)

流程上是这样的:

  1. 用户使用用户名密码来请求服务器
  2. 服务器进行验证用户的信息
  3. 服务器通过验证发送给用户一个token
  4. 客户端存储token,并在每次请求时附送上这个token值
  5. 服务端验证token值,并返回数据

    组成

    JWT由三部分组成

    • header(包含类型和加密算法),经过base64加密,构成第一部分。
      {
      'typ': 'JWT',
      'alg': 'HS256'
      }
    • playload,可以用来存放一些不敏感的信息。经过base64加密,构成第二部分。
    • signature,由前面两个部分(base64后)跟一个secret进行加盐加密,构成第三部分。
HolyZheng commented 6 years ago

推荐阅读: 伯乐在线——HTTP 缓存机制一二三 IMWeb前端博客——HTTP缓存控制小结 IT笔录——http消息头

http缓存机制

关键头部字段

  • cache-control、 Pragma
  • if-Match、if-None-Match
  • if-Modified-Since、if-Unmodified-Since
  • ETag
  • Expires、Last-Modified

    Pragma

    http1.0可用,现在为了向下兼容,也设置该头部,只有一个值:no-cache禁用缓存


    Expires

    设置缓存时间(该时间相对于服务器),接受一个GMT(格林尼治时间),用来告诉浏览器过期时间,如果还没有过这个时间则不发送请求。

    Expires: Sun Jul 15 2018 19:13:07 GMT

    cache-control

    也可用来设置缓存时间,http1.1,三者优先级:

    Pragma > Cache-Control > Expires

    可设置多个值,比如常用的:no-cache, max-age, public, private


    Last-Modified

    接受一个格林尼治时间,说明资源的最近一次的修改时间,该字段的作用是当某个资源保存的缓存时间过期了,但服务器并没有更新过这个资源,那么可以告诉客户端此资源没有更新,可以获取缓存中的内容(返回304,不返回实体内容)


    if-Modified-Since

    Last-Modified的值会在下一次的请求中通过if-Modified-Since传递给服务器,如果它的值和此时服务器的Last-Modified值一致,说明没有修改,服务器返回304。如果不一致则当作正常请求处理,返回资源和200状态码。


    ETag

    服务端资源有可能被更新了,但是实际内容并没有改变。但是这样依然会引起Last-Modified的更新,服务器给客户端返回没有任何改变的内容。为了解决这个问题,引入了ETag。用于http1.1。 服务器为资源生成一个唯一的字符串,如通过md5编码。只要不变,生成的字符串就不变。在客户端请求资源的时候,将该ETag一起返回给客户端,客户端保留该ETag,下次请求的时候带上。然后比较ETag,相同则表示内容相同,返回304;不同,返回资源和200状态码。


    If-None-Match

    ETag的值会通过if-None-Match头部传递给服务器,然后服务器比较ETag的值,相同则表示内容相同,返回304;不同,返回资源和200状态码。


    另外的 if-Match,if-Unmodified-Since

    他们不是用来实现缓存策略的,而是用来优化并发控制,他们的作用是,使得当前请求成为条件式请求:只有当资源在指定的时间之后没有进行过修改的情况下,服务器才会返回请求的资源,或是接受 POST 或其他 non-safe 方法的请求。例如在某些场景:假如在原始副本获取之后,服务器上所存储的文档已经被修改,那么对其作出的编辑会被拒绝提交。

总结

  1. Expires / Cache-Control用来设置缓存时间,即资源有效时间。状态码 200(from cache),可避免请求发送到服务器。
  2. Last-Modified / ETag用来判断资源是否被修改了。状态码 304(not change),可避免传输相同的资源内容,造成带宽和时间的浪费。

    使用原则

    • 需要兼容HTTP1.0的时候需要使用Expires,不然可以考虑直接使用Cache-Control
    • 需要处理一秒内多次修改的情况,或者其他Last-Modified处理不了的情况,才使用ETag,否则使用Last-- Modified。
    • 对于所有可缓存资源,需要指定一个Expires或Cache-Control,同时指定Last-Modified或者Etag。
    • 可以通过标识文件版本名、加长缓存时间的方式来减少304响应。
HolyZheng commented 6 years ago

WebSocket

websocket协议的特点:建立在 TCP 协议之上,默认端口也是80和443,服务器可以主动向客户端推送消息,客户端也可以向服务器发送消息,双向平等对话。 阮一峰WebSocket 教程

HolyZheng commented 6 years ago

http1.1

持续连接

http1.1协议使用了持续连接,所谓持续连接就是在服务器响应了请求之后后仍然可以保持一段时间的连接,使得我们可以继续在此次连接上发送后续的http请求和响应。

两种工作方式

  1. 非流水线方式:客户收到前一个请求的响应后,才能发送下一个请求。在这种工作方式下,比起http1.0每次请求都要重新建立连接(需要2倍RTT的开销),http1.1在首次建立连接后,后续的每个请求只需1个RTT的开销。
  2. 流水线方式:客户在收到前一个请求的响应之前就可以发送下一次请求。在这种工作模式下,一个RTT时间内,可以处理多个请求。

http2.0

二进制传输

相比于1.0的通过文本方式传输数据,2.0采用二进制方式传输数据;文本的表现形式有多样性,要考虑的场景比较多,而二进制只有0和1,解析速度更快。

多路复用

http1.1中,会存在一个叫做“对头阻塞”的问题,因为在1.1中,在接受响应的时候,要按照请求发送的顺序来接收响应,如何前面的请求阻塞了,后面的请求即使处理完了,也要继续等待。 http2.0 引入了多路复用来解决,它引入了两个关键的概念——“帧(frame)”和“流(stream)”。

HolyZheng commented 5 years ago

计算机网络分层

工作

  1. 应用层:各种应用软件
  2. 表示层:数据格式的表示,压缩加密功能
  3. 会话层:控制应用程序之间会话能力
  4. 传输层:端到端传输数据
  5. 网络层:负责不同设备的通讯,数据转发
  6. 数据链路层:定义基本的数据格式,如何传输,如何标识
  7. 物理层:一些硬件,负责底层的数据传输

协议

  1. 传输层:UDP 用户数据协议,tcp(传输控制协议)
  2. 应用层:HTTP 超文本传输协议,HTTPS, 全称Hyper Text Transfer Protocol Secure(超文本传输安全协议),比http多了一个TLS(SSL)层,https是HTTP运行在SSL/TLS之上,SSL/TLS运行在TCP之上。
HolyZheng commented 3 years ago

cors 跨域

配置 access-control-allow-origin 头遇到的问题:

  1. 配置多个域名的时候浏览器报错:
    the 'Access-Control-Allow-Origin' header contains multiple values xxx, but only one is allowed.

    解决方法,判断origin,命中域名后再设为Access-Control-Allow-Origin的值

    if (corsHost.host.includes(ctx.request.origin)) {
     ctx.set('Access-Control-Allow-Origin', ctx.request.origin);
     ctx.set('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept');
     ctx.set('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE');
    }
  2. 当前端开启 withCredentials: true 后,服务Access-Control-Allow-Origin的值不允许设为通配符 ‘ * ’。解决方法同上,或设为某一具体域名。
    The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' 
    when the request's credentials mode is 'include'.
  3. 客户端设置域名的时候要注意域名的配置,cookie也是跟域名的。所以可以将domain设置为父域名来进行跨域携带
    document.cookie = 'name=value;domain=.xx.com;'