http的发展史与三次握手、四次挥手的过程,附https的握手过程

741 阅读12分钟

http的版本号

在面试中,我们经常会被问到,http1.1与http2之间的区别,现在,我们来看一下几个http版本之间的区别。

http/0.9:

此版本的http协议已经过世了,现在基本没用了。它只支持GET请求方式,并且只能请求访问HTML格式的资源,没有在通讯中指定版本号,并且不能设置请求头

http/1.0

这是第一个在通讯中指定版本号的http协议版本,增加了请求方式POST和HEAD;请求资源不再局限于HTML格式了,根据Content-Type可以支持多种数据格式;此版本还包括了状态码(status code)、多字符集支持、多部分发送(multi-part type)、权限(authorization)、缓存(cache)、内容编码(content encoding)等。

缺点:每次tcp链接只能发送一个请求,当服务器相应之后,就会关闭链接,下一个请求会重新建立一个tcp链接

http/1.1

  • 默认采用持续链接(每个tcp链接可以被多个请求复用,不用声明Connection: keep-alive)
  • 增加了管道机制,一个tcp链接可以同时发送多个请求,这样增加了并发性
  • 1.1版本规定可以不使用content-length字段,而使用“分块传输编码”。只要请求或回应的头信息有transfer-Encoding字段,就表明回应将由数量未定的数据块组成。Transfer-Encoding: chunked
  • 新增了请求方式:PUT、PATCH、OPTIONS、DELETE 分块传输编码:超文本传输协议中的一种传输机制,允许http由服务端发送个客户器的的数据分成多份,分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供 缺点:http/1.1版本虽然支持多个请求同时发送,但是同一个TCP连接里,所有的数据通信是按次序进行的,也就是服务端只能一个一个的处理,这就导致回应慢,会有很多请求排队,造成队头堵塞

http/2

  • 在2015年5月作为互联网标准正式发布,增加了双工模式,即不仅客户端可以同时发送多个请求,服务端也能同时处理多个请求,这就解决了队头堵塞的问题。
  • 采用二进制格式传输数据,而非文本格式
  • 使用多路复用的技术。
  • 增加服务器主动推送的功能,也就是服务端可以主动向客户端推送消息 http/2引入了数据帧和流的概念,其中数据帧中会有数据的顺序标识,这样服务端在收到数据之后就可以根据顺序合并出完整的数据,这就是服务端可以同时处理多个请求的原因。而流就可以使数据被标识顺序的数据并行传输。帧和流是http/2中非常重要的两个概念。

帧(Frame)

http/2中数据传输的最小单位,因此帧不仅要细分表达 HTTP/1.x 中的各个部份,也优化了 HTTP/1.x 表达得不好的地方,同时还增加了 HTTP/1.x 表达不了的方式。 每一帧都包含几个字段,有length、type、flags、stream identifier、frame playload等,其中type 代表帧的类型,在 HTTP/2 的标准中定义了 10 种不同的类型,包括上面所说的 HEADERS frame 和 DATA frame。此外还有: PRIORITY(设置流的优先级) RST_STREAM(终止流) SETTINGS(设置此连接的参数) PUSH_PROMISE(服务器推送) PING(测量 RTT) GOAWAY(终止连接) WINDOW_UPDATE(流量控制) CONTINUATION(继续传输头部数据)

在 HTTP 2.0 中,它把数据报的两大部分分成了 header frame 和 data frame。也就是头部帧和数据体帧。

流(stream)

存在与链接中的一个虚拟通道。流可以承载双向信息,每个流都有一个唯一的整数ID,一个完成的请求或响应称为一个数据流。流具有一下几个特点:

  • 双向性:同一个流内,可同时发送和接受数据
  • 有序性:流中被传输的数据就是二进制帧 。帧在流上的被发送与被接收都是按照顺序进行的
  • 并行性:流中的 二进制帧 都是被并行传输的,无需按顺序等待
  • 流的创建:流可以被客户端或服务器单方面建立, 使用或共享
  • 流的关闭:流也可以被任意一方关闭
  • HEADERS 帧在 DATA 帧前面
  • 流的 ID 都是奇数,说明是由客户端发起的,这是标准规定的,那么服务端发起的就是偶数了

多路复用

http/2对同一域名下的所有请求都是基于流的,也就是说同一域名,不管访问多少文件,都只建立一路链接,假如在http/1.1时,服务端的最大并发数是60,浏览器发起请求的最大并发数是6,那么,服务器实际的最大并发数就是10了,因为一个浏览器就会占用6个。在http/2中,因为所有的请求都是基于流的,那么,只建立一路链接,后续所有的请求都通过流传输,服务器的最大并发数就还是60,比原来提升了整整6倍。

http请求的三次握手和四次挥手

三次握手

image.png 从上图中简单的理解下http的三次握手的过程

  • 第一次,客户端发起http请求,将tcp的控制位SYN置为1,并生成一个随机数作为序列号(req),随机数的范围在0-2^^32之间(相对序列号为1),然后发送到服务端
  • 服务端收到客户端发来的信息之后,也生成一个随机数作为序列号,并将客户端传过来的序列号加1,作为确认号(ack),同时,SYN,ACK控制位置为1,发送给客户端
  • 客户端收到服务端发送过来的消息之后,讲服务端发送过来的序列号加1作为确认号,然后ACK控制位置为1,发送给服务端 经此三个步骤之后,客户端与服务端确认了身份,是对的人,然后就建立了链接,就开始数据的传输 下面看一下使用wireshark抓包的数据,详细说一下序列号与确认号

image.png 图中是我自己使用node的net模块写的客户端与服务端通信的demo的一个抓包数据,其中前面三次为三次握手的过程,后面的是数据传输的部分,暂时不用看

  • 看下面的详细数据,其中Sequence Number 为 0,这跟我们上面讲的是0-2^^32之间的随机数有冲突啊,其实不然,仔细看在Sequence Number后面还有说明——relation sequence number。什么意思呢,就是相对序列号的意思,想对于本次链接,这是第一次发起的请求,所以从0开始计的,在下面还有一个Sequence Number (raw),这个值就是实际的序列号了
  • Acknowledgment Number:可以从图中看到,不管是相对确认号还是实际确认号,都是0,因为我们在第一次握手的时候,可以说是没有确认号的,所以,其值为0
  • 再看 Flags下面的Syn控制位,其值是不是置为了1
  • 另外还有一个属性,就是 Tcp Segment Len,这个表示我们传输的数据的长度,这个在后面每次传输数据时,会用来计算确认号的,简单点说,就是服务器返回给客户端数据时,其确认号为客户端像服务端请求时的序列号加上请求的Tcp Segment Len

image.png 这是第二次握手的信息,与第一次握手时不同的是,其Acknowledgment控制位置为1,并且其相对确认号(Acknowledgment Number)为 1

image.png 而第三次握手时的信息就只有确认号了,Syn控制位置为0,Acknowledgment控制位置为1,相对序列号与相对确认号都为1

至此,三次握手就完成了,接下来就可以传输数据了

四次挥手

image.png http四次挥手的过程如上图

  • 客户端先发送一个断开链接的请求到服务端,此请求中,tcp的FIN控制位为1,ACK控制位也为1,会传递一个序列号和一个确认号,这里的序列号的值是根据前面传递数据的长度来计算的,计算方式前面已经讲过了,确认号ack的值也是一样计算来的
  • 服务端收到客户端的断开链接的请求之后,会向客户端回一个消息,表示我收到你断开链接的请求了,其ACK控制位为1,序列号同样式根据之前传输的数据长度计算来的,确认号就是客户端请求服务端时的序列号+1
  • 在回复了客户端的断开链接请求之后,服务端会先看自己是否还有数据没有传输完,如果没有,会再次向客户端发送一条信息,表示我也要断开链接了,其FIN、ACK控制位为1,序列号和确认号跟上次一样
  • 客户端在收到服务端的断开链接请求之后,也会进行回复,其ACK控制位为1,序列号为x+1,确认号为客户端请求时的序列号+1

至此,四次挥手的过程就结束了,感兴趣的同学可以自己使用抓包工具看下四次挥手过程的其他信息,这里就不一一介绍了。

为什么握手是三次,而挥手却是四次呢? 其实握手过程理论上应该也是四次的,不过是将后面两次合并了,因为链接的建立只需要确认是否是“对的人”就行,但是,断开链接的时候,总得服务端和客户端的数据都传送完了才能断开吧,所以,挥手的时候多了一个服务端向客户端发送断开链接的请求

https

什么是https协议,与http协议又有什么区别呢?

简单点讲就是,https = http + TLS;

http协议的信息是明文传输的,没有进行任何加密,这样传输数据是不安全的,一旦链接被劫持,数据也将泄露,所以https诞生了,就是在http的基础上加了一层SSL协议。SSL协议位于TCP/IP与各应用层协议之间,为数据通信提供安全支持。

SSL协议与TLS协议

SSL协议可分为两层:

  • SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等支持
  • SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际数据传输之前,通讯双方的身份认证、协商加密算法、交换加密密匙等 而TLS协议其实跟SSL协议是一个东西,TLS是SSL的升级版,在1999年,互联网标准化组织ISOC接替NetScape公司,发布了SSL的升级版TLS 1.0版。 既然知道了https就是http的安全版,那么https的握手过程是怎样的呢?

SSL的握手过程

盗用网络上的一张图

image.png 从图中可以看出,SSL的握手过程比http要复杂的多,大致可分为四步:

  • 客户端请求建立一个TLS链接,并发送一个随机数1(同http中序列号一样)和客户端支持的加密套件,比如RSA,此时是明文传输
  • 服务端收到客户端的请求之后,从客户端支持的加密套件中选一个,然后将证书、TSL协议版本号、随机数2一起其他相关信息回传给客户端
  • 客户端收到服务端的证书之后,会验证证书是否合法一起是否过期,都没问题之后,客户端会生成一个随机数3,再使用服务器传递过来的证书中的非对称加密的公匙对随机数进行加密,然后将加密后的数据传给服务端(如果服务端要求对客户端的身份进行认证,那客户端也会把自己的证书等信息一起传给服务端,供服务端进行身份验证)
  • 服务端收到客户端发送的数据之后,用密匙对数据进行解密,然后得到随机数3,然后利用随机数1、随机数2、随机数3通过对称机密算法生成一个对称加密key(后续的数据传递都是用这个密匙进行加解密的,客户端也会生成一个同样的key),然后再向客户端Finish消息,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和session secret(也就是对称加密密匙)加密数据了。此次发送的消息也是加密了的,用以验证之前握手建立起来的加解密通道是否成功

到此,https的四次握手过程就结束了十二、HTTPS的七次握手(TCP三次+TLS四次)_I want to know a little more.-CSDN博客_https四次握手

我们一般说https的四次握手,其实就是TLS的四次握手

总结

讲到这里,http的发展署和http与https的握手过程就结束了,https的握手过程,其实就是SSL/TLS 的握手过程,关于SSL/TLS更多的底层知识,大家可以阅读一下这篇文章

HTTPS的七次握手(TCP三次+TLS四次)_I want to know a little more.-CSDN博客_https四次握手