http1.0/1.1/2.0/3.0

http1.0

  • http是无状态链接,即他只管链接,不管你们之前是否链接过,故通常通过设置cookie来记录用户的登录状态,服务器生成session来用记录用户登录的上下文,并生成sessionId来唯一标识这条记录,然后将其放到响应头李,后续浏览器发起请求再次带上该请求头,即可分辨其用户状态;
  • http基于TCP链接,从建立链接到断开要经过三次握手以及四次挥手,并且一个http链接只新建一个tcp链接,请求以及响应以文本形式传输,每次传输完数据就断开链接;
  • 同时如果发生了丢包,需要重新建立tcp链接
  • 这就导致了http1.0下传输效率其实并不高,每个资源的请求以及响应都要在队列中进行排队,等待传输

http1.1

  • 为了解决上面的问题,提出了http1.1
  • http1.1默认使用长链接,减少了tcp建立链接耗费的时间
  • 同时http1.1支持pipeline,即允许在一个tcp连接上发起多个请求,但是这种特性有个限制,就是虽然可以发起多个请求,但请求本身的发起是有先后顺序的,同时要求服务器的返回也需要按照这个顺序返回,不然无法识别响应对应哪个请求
  • 也就是http1.1的pipeline其实节省的是发起请求的时间,允许同时发起请求,而无需等下一个请求回来后再发起第二个请求
  • 但由于这种机制限制较多,实现起来比较麻烦,现代浏览器多数是通过建立多个tcp链接来实现并发的,同时由于浏览器本身的限制,一并允许兵法的tcp链接数量为6个

http2.0

  • 为了真正解决并发的问题,提出了http2.0
  • http2.0采用了叫做多路复用的技术,就是将报文以二进制的形式编码,同时将其分为多个帧,叫做二进制帧,同一个请求的二进制帧带有相同的标识,供接收方将其拼凑成一个完整的报文
  • 同时http2.0所有请求都是建立在一个tcp连接上,通过二进制帧的技术,无需像http1.1那样要求响应顺序与请求顺序一致,服务器先收到哪个请求就先响应该请求,浏览器可以通过标识得到完整报文
  • 另外,http2.0还采用了头部压缩的技术,简单讲就是在服务器和浏览器各自维护一份相同的请求头字典,后续请求头的发送就直接用字典的key值进行代替,减少传输量
  • 并且http2.0允许从服务器推送消息到浏览器,通过预测浏览器的请求,服务器可以提前把所需资源推送给浏览器,减少资源传输的时间
  • 但是http2.0依然有没被解决的问题,那就是丢包时的性能问题
  • 由于tcp协议本身的限制,数据传输采用的是应答机制,数据包发送后需要得到接收方的回复,若超时未收到回复,即认为当前发送的包丢失了,需要重新发送
  • 同时tcp通过“滑动窗口”的机制来提升传输效率,即尽可能多的发送数据包而无需等待,但这个无需等待发送的量是有上限的,换句话说他是通过批量发送。批量确认应答来进行数据传输,发送方会根据收到的最大连续序列的包来移动窗口,而如果某个包丢失了,没有发回应答,那么窗口就会停止移动,进行数据包的重新发送
  • 而http2.0的所有请求都是建立在一个tcp请求上的,也就是说某个请求的丢包会阻塞别的请求的发送

QUIC(http3.0)

  • QUIC - quick udp internet connection,是谷歌提出的一个协议,他放弃了使用tcp而转向udp协议
  • udp与tcp不同,无需等待应答,一旦建立链接,只管进行数据的发送,一般用在实时通话或视频等,对时效性要求高的场景中
  • QUIC解决http2.0的阻塞问题,根本思路就是,无需批量等待应答,某个数据包的应答收到后,就将窗口后移,发送下一个包
  • tcp的数据传输是基于sequence_no和ack来确保可靠性的,其中sequence_no是数据包中字节的序号,而ack是基于sequence_no加一,发生丢包时,必须等待该包重新发送,并收到ack应答,才能继续往下走,否则如果跳过丢失的包继续往前走,就无法知道哪些包丢失了
  • 结合前面的滑动窗口,接收方会根据自身收到的包,对应发回ack
  • 如果接收方接收到的sequence_no是连续的,发送方只需要确认最后一个ack即可,根据这个ack即可移动窗口
  • 但如果发现数据包中的sequence_no不是连续的,接收方就会返回最近一个ack,当发送方接收到3次相同的ack时,就得知数据丢包了,就要重新进行数据的发送,同时因为发送方不知道除了ack代表的那个包丢失外还有没有别的包丢失了,所以很可能需要将丢失包开始的所有数据重新发送一遍,即使接收方可能已经接收到了这些包,所以tcp丢包时不仅造成阻塞还浪费带宽
  • QUIC,它采用的是packet_no来确保可靠性,该标识从0开始,每发送一个包就加一,即使丢包了,重新发送时也是基于当前的packet_no加一
  • 同时,QUIC利用多路复用时的strem_id以及QUIC新增的stream_offset来判断当前的数据包的正确序列,offset即当前数据包在整个数据流中的偏移量,这样即使packet_no不一致,也可以通过stream_id和stream_offset识别数据包顺序进行重组,换句话说QUIC支持乱序传输数据
  • 与tcp不同,中间ack的丢失对数据传输影响不大,因为其只需要确认最后一个ack即可,但QUIC要求每个数据包都有明确的ack返回,没返回的就认为是丢包了
  • QUIC就是通过这种方法提供数据的传输效率
  • QUIC另外还提供了纠错机制,通过增加一个冗余包的发送,当发生仅一个包丢失的时候,可以根据之前接收的包与冗余包反推出丢失的那个包
  • 原理是将所有数据包进行异或求值得出冗余包,即假设有5个包,异或出一个冗余包,共六个,根据异或的原理

    • 相同数异或为0
    • 0与任何数异或等于那个数本身
  • 假设现在丢失了3号包,只需要将1、2、4、5以及冗余包一起进行异或运算即可得到3号包
  • 虽然这种纠错机制只能在仅丢失一个包的基础上生效,但根据网络环境,选取适当的包的总数进行异或处理,可能基本防止丢包重传的情况
  • 最后,QUIC采取了类似TFO(TCP fast open)的思想,通过cookie的缓存识别客户端身份,实现了首次连接耗时1-RTT(Round-Trip Time),后续连接0-RTT的开销

https:

  • 简单说一下对称加密和非对称加密
  • 对称加密,通过一个token对数据进行加密编码,服务器接收到加密数据后用同一个token解密,但这种形式容易被破解
  • 非对称加密,使用公钥加密,只能用私钥才能解开,所以服务器生成公钥,然后传给客户端,客户端使用公钥加密后,回传服务器,服务器用私钥解密,这样能防止信息被盗,但非对称加密运算量大,十分消耗性能
  • 通常采用对称加密和非对称加密相结合的方法,客户端请求服务器,服务器生成一个公钥传给客户端,客户端生成一个随机数,利用公钥,进行非对称加密,然后把这个加密的信息返回服务器,服务器利用私钥进行解码,得到客户端生成的随机数,后续数据传输,客户端使用自己生成的随机数对信息进行对称加密,这样就既保证对称加密token不被暴露,也保证了传输效率

你可能感兴趣的:(html5)