请讲一下HTTP长连接和短连接?
在HTTP/1.0中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,但任务结束就中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话。
但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议,会在响应头有加入这行代码:Connection:keep-alive
在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
HTTP协议的长连接和短连接,实质上是TCP协议的长连接和短连接。
URL是什么?由哪几部分组成?
HTTP使用统一资源标识符(Uniform Resource Identifiers,URI)来传输数据和建立连接
URL是一种特殊类型的URI,包含了用于查找某个资源的足够的信息,全称Unifor Resource Locator,中文叫统一资源定位符,是互联网上用来标识某一处资源的地址
URL的各部分组成:
www.aspxfans.com:8080/news/index.…
协议部分:该URL使用的是http协议,在Internet中可以使用多种协议,如HTTP,FTP等等 //是分隔符
域名部分:该URL使用的是域名部分为“www.aspxfans.com”,一个URL中可以使用IP地址作为域名使用
端口部分:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符,端口不是一个URL必须的部分,如果忽略将采用默认端口
虚拟目录部分:从域名后的第一个/开始到最后一个/为止,是虚拟目录部分,虚拟目录也不是一个URL必须的部分,该URL中的虚拟目录部分是/news/
文件名部分:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和 “#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件 名是“index.asp”。文件名部分也不是一个 URL 必须的部分,如果省略该部分, 则使用默认的文件名
锚部分:从#号开始到最后,都是锚部分,该URL的锚部分是“name”,锚部分也不是一个URL必须的部分
参数部分:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
HTTP请求报文和响应报文的格式?
请求报文格式:
- 请求行(请求方法+URI协议+版本)
- 请求头部
- 空行
- 请求主体
GET/sample.jspHTTP/1.1 请求行
Accept:image/gif.image/jpeg, 请求头部
Accept-Language:zh-cn
Connection:Keep-Alive
Host:localhost
User-Agent:Mozila/4.0(compatible;MSIE5.01;Window NT5.0)
Accept-Encoding:gzip,deflate
username=juejin&password=1234 请求主体
响应报文:
- 状态行(版本+状态码+原因短语)
- 响应首部
- 空行
- 响应主体
HTTP/1.1 200 OK
Server:Apache Tomcat/5.0.12
Date:Mon,6Oct2022 16:45:12 GMT
Content-Length:112
<html>
<head>
<title>HTTP响应示例<title>
</head>
<body>
Hello HTTP!
</body>
</html>
HTTP1.0和HTTP1.1的区别有哪些?
- 长连接:HTTP 1.1支持长连接(Persistent Connection)和请求的流水线(Pipelining)处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启
Connection: keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。 - 缓存处理:在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略,可供选择的缓存头来控制缓存策略。
- 带宽优化及网络连接的使用:HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
- 错误通知的管理:在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。
- Host头处理:在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)。
HTTP1.1和HTTP2.0的区别有哪些?
HTTP2.0相比HTTP1.1支持的特性:
- 新的二进制格式:HTTP1.1的解析是基于文本。基于文本协议的格式解析存在天然缺陷,文本的表现形式有多样性,要做到健壮性考虑的场景必然很多,二进制则不同,只认0和1的组合。基于这种考虑HTTP2.0的协议解析决定采用二进制格式,实现方便且健壮。
- 多路复用,即连接共享,即每一个request都是用作连接共享机制的。一个request对应一个id,这样一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方可以根据request的 id将request再归属到各自不同的服务端请求里面。
- 头部压缩,HTTP1.1的头部(header)带有大量信息,而且每次都要重复发送;HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。
- 服务端推送:服务器除了对最初请求的响应外,服务器还可以额外的向客户端推送资源,而无需客户端明确的请求。
HTTP与HTTPS的区别?
- HTTP是明文传输,数据都是未加密的,安全性较差;HTTPS即SSL+HTTP,数据传输过程是加密的,安全性较好
- 使用HTTPS协议需要到CA(Certificate Authority数字证书认证机构)申请证书
- HTTP页面响应速度比HTTPS快,主要是因为HTTP使用TCP三次握手建立连接。客户端和服务器需要交换3个包,而HTTPS除了TCP的三个包还要加上SSL握手需要的9个包,所以一共是12个包
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443
- HTTPS其实就是建构在SSL/TLS之上的HTTP协议,所以HTTPS比HTTP要更耗费服务器资源
请讲下HTTPS的原理?
加密流程按图中的序号分为:
-
客户端请求 HTTPS 网址,然后连接到 server 的 443 端口 (HTTPS 默认端口,类似于 HTTP 的80端口)。
-
采用 HTTPS 协议的服务器必须要有一套数字 CA (Certification Authority)证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被篡改。
-
服务器响应客户端请求,将证书传递给客户端,证书包含公钥和大量其他信息,比如证书颁发机构信息,公司信息和证书有效期等。
-
客户端解析证书并对其进行验证。如果证书不是可信机构颁布,或者证书中的域名与实际域名不一致,或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。
如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥A。然后客户端还会生成一个随机码 KEY,并使用公钥A将其加密。
-
客户端把加密后的随机码 KEY 发送给服务器,作为后面对称加密的密钥。
-
服务器在收到随机码 KEY 之后会使用私钥B将其解密。经过以上这些步骤,客户端和服务器终于建立了安全连接,完美解决了对称加密的密钥泄露问题,接下来就可以用对称加密愉快地进行通信了。
-
服务器使用密钥 (随机码 KEY)对数据进行对称加密并发送给客户端,客户端使用相同的密钥 (随机码 KEY)解密数据。
-
双方使用对称加密愉快地传输所有数据。
在浏览器中输入url后执行的全部过程?
首先是解析域名,找到主机IP。浏览器利用IP直接与网站主机通信,三次握手,建立TCP连接。浏览器会以一个随机端口向服务端的web程序80端口发起TCP的连接。建立TCP连接后,浏览器向主机发起一个HTTP请求,服务器响应请求,返回响应数据。浏览器解析响应内容,进行渲染,呈现给用户。
涉及:DNS TCP IP HTTP协议等
一个用户从发起请求到接收到响应,中间经过了哪些服务,每个服务做什么事情?
概要图:
- 用户输入url,浏览器内部代码将url进行一个拆分解析
- 浏览器它首先会先去找本地的hosts文件,检查在这个文件中是否有相应的域名、IP对应关系,如果有的话 ,则向这个IP地址发送请求,如果没有的话就发送给DNS域名解析器进行解析,将域名解析成对应的服务器IP地址,发回给浏览器
注释:(结合上图看)
浏览器客户端向本地DNS服务器发送一个含有域名www.juejin.cn的DNS查询报文。
本地DNS服务器把查询报文转发到根DNS服务器,根DNS服务器注意到其com后缀,于是向本地DNS服务器返回comDNS服务器的IP地址。
本地DNS服务器再次向comDNS服务器发送查询请求,comDNS服务器注意到其www.juejin.cn 后缀并用负责该域名的权威DNS服务器的IP地址作为回应。
最后,本地DNS服务器将含有www.juejin.cn的IP地址的响应报文发送给客户端。
- 拿到服务器ip后,接下来就是网络通信(过程如下图),分层由高到底分别为:应用层、传输层、网络层、数据链路层。发送端从应用层往下走,接收端从数据链路层往上走
首先 :应用层客户端发送http请求
HTTP请求包括请求报头和请求主体两个部分,其中请求报头包含了至关重要的信息,包括请求的方法(GET/POST)、目标url、遵循的协议(http/https/ftp...),返回的信息是否需要缓存,以及客户端是否发送cookie等
然后:传输层TCP传输报文
3次握手,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序的80端口发送请求,这个请求到达服务器端后,就建立了TCP/IP的连接
三次握手机制:
- 第一次握手:客户端请求建立连接,向服务端发送一个同步报文(SYN=1),同时选择一个随机数 seq = x 作为初始序列号,并进入SYN_SENT状态,等待服务器确认。
- 第二次握手::服务端收到连接请求报文后,如果同意建立连接,则向客户端发送同步确认报文(SYN=1,ACK=1),确认号为 ack = x + 1,同时选择一个随机数 seq = y 作为初始序列号,此时服务器进入SYN_RECV状态。
- 第三次握手:客户端收到服务端的确认后,向服务端发送一个确认报文(ACK=1),确认号为 ack = y + 1,序列号为 seq = x + 1,客户端和服务器进入ESTABLISHED状态,完成三次握手。
理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。
当数据传输完毕,连接的双方都会通知对方要释放此链接(四次挥手)
接着:网络层IP协议查询MAC地址
IP协议的作用是把TCP分割好的各种数据包传送给接收方。而要保证确实能传到接收方还需要接收方的MAC地址,也就是物理地址。IP地址和MAC地址是一一对应的关系,一个网络设备的IP地址可以更换,但是MAC地址一般是固定不变的。ARP协议可以将IP地址解析成对应的MAC地址。当通信的双方不在同一个局域网时,需要多次中转才能到达最终的目标,在中转的过程中需要通过下一个中转站的MAC地址来搜索下一个中转目标。
数据到达数据链路层
在找到对方的MAC地址后,就将数据发送到数据链路层传输。这时,客户端发送请求的阶段结束
再次:服务器接收数据
接收端的服务器在链路层接收到数据包,再层层向上直到应用层。这过程中包括在运输层通过TCP协议将分段的数据包重新组成原来的HTTP请求报文。
服务器响应请求
服务接收到客户端发送的HTTP请求后,查找客户端请求的资源,并返回响应报文,响应报文中包括一个重要的信息——状态码。状态码由三位数字组成,
其中比较常见的是200 OK表示请求成功。
301表示永久重定向,即请求的资源已经永久转移到新的位置。在返回301状态码的同时,响应报文也会附带重定向的url,客户端接收到后将http请求的url做相应的改变再重新发送。
404 not found 表示客户端请求的资源找不到。
最后:服务器返回相应文件
服务器端收到请求后的由web服务器(准确说应该是http服务器)处理请求,诸如Apache、Ngnix、IIS等。web服务器解析用户请求,知道了需要调度哪些资源文件,再通过相应的这些资源文件处理用户请求和参数,并调用数据库信息,最后将结果通过web服务器返回给浏览器客户端。
关闭TCP连接
为了避免服务器与客户端双方的资源占用和损耗,当双方没有请求或响应传递时,任意一方都可以发起关闭请求。与创建TCP连接的3次握手类似,关闭TCP连接,需要4次挥手。
-
第一次挥手:客户端向服务端发送连接释放报文(FIN=1,ACK=1),主动关闭连接,同时等待服务端的确认。
- 序列号 seq = u,即客户端上次发送的报文的最后一个字节的序号 + 1
- 确认号 ack = k, 即服务端上次发送的报文的最后一个字节的序号 + 1
-
第二次挥手:服务端收到连接释放报文后,立即发出确认报文(ACK=1),序列号 seq = k,确认号 ack = u + 1。
这时 TCP 连接处于半关闭状态,即客户端到服务端的连接已经释放了,但是服务端到客户端的连接还未释放。这表示客户端已经没有数据发送了,但是服务端可能还要给客户端发送数据。
-
第三次挥手:服务端向客户端发送连接释放报文(FIN=1,ACK=1),主动关闭连接,同时等待 A 的确认。
- 序列号 seq = w,即服务端上次发送的报文的最后一个字节的序号 + 1。
- 确认号 ack = u + 1,与第二次挥手相同,因为这段时间客户端没有发送数据
-
第四次挥手:客户端收到服务端的连接释放报文后,立即发出确认报文(ACK=1),序列号 seq = u + 1,确认号为 ack = w + 1。
此时,客户端就进入了
TIME-WAIT状态。注意此时客户端到 TCP 连接还没有释放,必须经过 2*MSL(最长报文段寿命)的时间后,才进入CLOSED状态。而服务端只要收到客户端发出的确认,就立即进入CLOSED状态。可以看到,服务端结束 TCP 连接的时间要比客户端早一些。- 第一次挥手:客户端向服务端发送连接释放报文(FIN=1,ACK=1),主动关闭连接,同时等待服务端的确认。- 序列号 seq = u,即客户端上次发送的报文的最后一个字节的序号 + 1
- 确认号 ack = k, 即服务端上次发送的报文的最后一个字节的序号 + 1