HTTP及浏览器篇
1.https和http的区别有哪些
解答
URL 前缀
:HTTP 的 URL 以 http:// 开头;HTTPS 的 URL 以 https:// 开头。默认端口号
:HTTP 默认使用 80 端口;HTTPS 默认使用 443 端口。协议安全性
:HTTP 是明文传输协议,数据在传输过程中容易被窃取和篡改;HTTPS 是安全的超文本传输协议,它在 HTTP 的基础上加入了 SSL/TLS 协议,通过加密和身份验证机制保证数据传输的安全性。证书
:HTTPS 需要使用 SSL/TLS 证书来验证服务器的身份,证书由权威的证书颁发机构(CA)颁发。
2. GET和POST有什么区别?
解答
请求参数的位置
:GET请求的请求参数会附加在URL之后,参数之间使用"&"连接,多个参数将会造成URL长度增加。而POST请求的请求参数则包含在请求体中,不会在URL中显示。请求长度的限制
:由于GET请求的参数附加在URL之后,因此其请求长度受限于浏览器对URL长度的限制(通常浏览器对URL的长度有限制,而服务器对URL的长度限制更为宽松)。而POST请求则没有这个问题,请求参数包含在请求体中,因此可以传输大量数据。安全性
:GET请求的参数会暴露在URL中,因此不能用于传输敏感信息,如密码等。而POST请求的参数在请求体中,不会在URL中显示,相对更加安全。然而,这并不意味着POST请求就一定比GET请求更安全,因为安全性还需要依赖于其他因素,如SSL/TLS加密等。幂等性
:GET请求是幂等的,即多次执行同一GET请求,服务器将返回相同的结果。而POST请求则不是幂等的,因为每次提交都会创建新的资源。(GET、PUT、DELETE是幂等的,多次请求效果相同。)缓存
:GET请求可以被缓存,而POST请求则不会,除非在响应头中包含适当的Cache-Control或Expires字段。后退/刷新按钮的影响
:GET请求可以被浏览器缓存,因此可以通过点击后退按钮或刷新按钮来重复执行。而POST请求则不会,因为这些操作对POST请求没有实际意义。
总的来说,GET和POST请求各有其特点和适用场景。GET请求通常用于请求数据,而POST请求则常用于提交数据。在选择使用哪种请求方法时,需要考虑到安全性、请求长度、幂等性等因素。
3.HTTP2相对于HTTP1.x有什么优势和特点?
解答
二进制分帧层
:HTTP/2不再使用文本格式来传输数据,而是将所有传输的信息分割为更小的消息和帧(frame),并以二进制格式进行编码。这有助于更高效地解析HTTP消息,并减少了解析错误的可能性。多路复用
:HTTP/2引入了多路复用技术,允许在单个TCP连接中并行处理多个请求和响应。这消除了HTTP/1.x中的队头阻塞问题,极大地提高了网络性能和资源利用率。头部压缩
:HTTP/2使用了头部压缩技术,通过共享头部信息,可以显著减少传输的数据量。这有助于减少延迟和网络带宽的消耗,特别是在传输大量小请求时效果更为显著。服务器推送
:HTTP/2允许服务器主动向客户端推送资源,而无需等待客户端的请求。这有助于减少往返时间,并提高网页加载速度。流量控制
:HTTP/2通过流控制、消息控制和窗口控制等机制,实现了对流量的精细控制,有助于防止网络拥塞和资源浪费。
总的来说,HTTP/2相对于HTTP/1.x在传输效率、安全性、网络性能等方面都有显著的提升。这些优势使得HTTP/2成为现代Web应用中广泛采用的协议标准。
4.HTTP2相对于HTTP1.x有什么优势和特点?
解答
强缓存
:通过设置 Expires
和 Cache - Control
响应头来控制。Expires 指定了缓存的过期时间,是一个绝对时间;Cache - Control 是一个更灵活的指令,常用的值有 max - age(指定缓存的有效时间,单位为秒)、no - cache(需要先向服务器验证缓存的有效性)、no - store(不使用缓存)等。
协商缓存
:当强缓存失效时,会使用协商缓存。通过设置 ETag
和 Last - Modified
响应头来实现。ETag 是资源的唯一标识符,Last - Modified 是资源的最后修改时间。客户端在后续请求时会发送 If - None - Match(对应 ETag)和 If - Modified - Since(对应 Last - Modified)请求头,服务器根据这些信息判断资源是否有更新,如果没有更新则返回 304 Not Modified 状态码,客户端使用本地缓存。
5.HTTP的状态码有哪些?
解答
- 2XX 成功
- 200 OK,表示从客户端发来的请求在服务器端被正确处理
- 204 No content,表示请求成功,但响应报文不含实体的主体部分
- 205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
- 206 Partial Content,进行范围请求
- 3XX 重定向
- 301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
- 302 found,临时性重定向,表示资源临时被分配了新的 URL
- 303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源
- 304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
- 307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
- 4XX 客户端错误
- 400 bad request,请求报文存在语法错误
- 401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
- 403 forbidden,表示对请求资源的访问被服务器拒绝
- 404 not found,表示在服务器上没有找到请求的资源
- 5XX 服务器错误
- 500 internal sever error,表示服务器端在执行请求时发生了错误
- 501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
- 503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
6.post请求为什么会多发送一次option请求
解答
POST 请求前发送的 OPTIONS 请求实际上是 HTTP 的一种特性,称为“预检请求”(Preflight request)。这主要发生在跨域请求(CORS, Cross-Origin Resource Sharing)的场景中,尤其是当请求涉及一些可能不太安全的方法(如 PUT、DELETE 或 POST)或使用了一些自定义的 HTTP 头部时。
预检请求的目的是检查服务器是否允许来自不同源(域、协议或端口)的请求进行某些操作。这样做可以确保客户端在发送实际请求之前,先得到服务器的明确许可。
OPTIONS 预检请求的主要特点和原因:
安全性
:HTTP 协议中的某些方法(如 GET、HEAD、POST)被认为是“安全”的,因为它们不会导致服务器上资源的状态发生变化。但是,其他方法(如 PUT、DELETE 等)可能会导致资源的创建、修改或删除。因此,在发送这些“非安全”请求之前,浏览器会先发送一个 OPTIONS 请求来询问服务器是否允许这样的操作。自定义头部
:如果请求中包含了某些自定义的 HTTP 头部,浏览器也会发送 OPTIONS 请求来询问服务器是否接受这些头部。CORS 配置
:服务器在响应 OPTIONS 请求时,可以通过 Access-Control-Allow-Methods、Access-Control-Allow-Headers 等头部来告诉浏览器它允许哪些方法和头部。如果服务器的响应中包含了这些头部,并且允许了客户端想要执行的操作,那么浏览器才会继续发送实际的 POST 请求。
7.http的请求和响应报文分别是什么样的?
解答
HTTP请求报文主要由:
请求行
、:请求行包含了HTTP方法(如GET、POST等)、请求的URI(资源的标识符)以及HTTP的版本号。请求头部
、:请求头部则包含了若干与请求相关的信息,如Accept-Charset(浏览器可接受的字符集)、Accept-Encoding(浏览器能够进行解码的数据编码方式)、Accept-Language(浏览器所希望的语言种类)等空行
: 空行用于分隔请求头部和请求正文请求体
: 则包含了需要发送给服务器的数据。
HTTP响应报文则主要由:
响应行
:包含了HTTP版本、状态码以及状态码的描述,用于描述请求的处理结果响应头部
:包含了与响应相关的元信息,如Content-Type(响应体的媒体类型)、Content-Length(响应体的长度)等。空行
: 空行用于分隔请求头部和请求正文响应体
:包含了服务器返回给客户端的数据。
需要注意的是,无论是请求报文还是响应报文,它们的格式都需要严格遵循HTTP协议的规定,以确保通信的正确性和可靠性。
8.同样是重定向307,303,302的区别?
Details
临时性与永久性
:307和302都是临时重定向,意味着请求的资源临时移到了不同的位置。客户端在将来的请求中可以继续使用原始URL,因为这个重定向只是暂时的。而303虽然也属于临时重定向,但其语义稍有不同,它主要用于将请求重定向到另一个URI,同时保留客户端的会话状态。请求方法的改变
:302允许各种各样的重定向,但并不能确保POST请求会重定向为POST。而303只允许任意请求重定向到GET,这意味着不论原始请求的方法是什么,重定向后的请求都会使用GET方法。至于307,它与302类似,但不允许POST请求被重定向为GET请求,即它会保持原有的请求方法不变。浏览器兼容性
:由于部分浏览器不能识别307响应,因此响应中需要包含必要的信息,如指向新的URI的超链接及简短说明,以便用户能够理解并向新的URI发出访问请求。而302和303则没有这方面的特殊要求。协议版本
:302和301是HTTP 1.0中的内容,而303、307等则是HTTP 1.1中引入的。
9.HTTP的keep-alive是干什么的?
Details
HTTP1.0 中默认是在每次请求/应答,客户端和服务器都要新建一个连接,完成之后立即断开连接,这就是短连接。当使用Keep-Alive模式时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接
,这就是长连接。其使用方法如下:
HTTP1.0版本是默认没有Keep-alive的(也就是默认会发送keep-alive),所以要想连接得到保持,必须手动配置发送
Connection: keep-alive
字段。若想断开keep-alive连接,需发送Connection:close字段;HTTP1.1规定了默认保持长连接,数据传输完成了保持TCP连接不断开,等待在同域名下继续用这个通道传输数据。如果需要关闭,需要客户端发送
Connection:close
首部字段。
Keep-Alive的建立过程
:
- 客户端向服务器在发送请求报文同时在首部添加发送Connection字段
- 服务器收到请求并处理 Connection字段
- 服务器回送Connection:Keep-Alive字段给客户端
- 客户端接收到Connection字段
- Keep-Alive连接建立成功
服务端自动断开过程
(也就是没有keep-alive):
- 客户端向服务器只是发送内容报文(不包含Connection字段)
- 服务器收到请求并处理
- 服务器返回客户端请求的资源并关闭连接
- 客户端接收资源,发现没有Connection字段,断开连接
客户端请求断开连接过程
:
- 客户端向服务器发送Connection:close字段
- 服务器收到请求并处理connection字段
- 服务器回送响应资源并断开连接
- 客户端接收资源并断开连接
开启Keep-Alive的优点
:
- 较少的CPU和内存的使⽤(由于同时打开的连接的减少了);
- 允许请求和应答的HTTP管线化;
- 降低拥塞控制 (TCP连接减少了);
- 减少了后续请求的延迟(⽆需再进⾏握⼿);
- 报告错误⽆需关闭TCP连;
开启Keep-Alive的缺点
:
- 长时间的Tcp连接容易导致系统资源无效占用,浪费系统资源。
总的来说,HTTP的keep-alive机制通过重用TCP连接和优化请求处理流程,提高了HTTP通信的性能和效率。
10. 从输入URL到看到页面的过程
答案
解析URL
: 首先会对 URL 进行解析,分析所需要使用的传输协议和请求的资源的路径。如果输入的 URL 中的协议或者主机名不合法,将会把地址栏中输入的内容传递给搜索引擎。如果没有问题,浏览器会检查 URL 中是否出现了非法字符,如果存在非法字符,则对非法字符进行转义后再进行下一过程。缓存判断
: 浏览器会判断所请求的资源是否在缓存里,如果请求的资源在缓存里并且没有失效,那么就直接使用,否则向服务器发起新的请求。DNS解析
: 下一步首先需要获取的是输入的 URL 中的域名的 IP 地址,首先会判断本地是否有该域名的 IP 地址的缓存,如果有则使用,如果没有则向本地 DNS 服务器发起请求。本地 DNS 服务器也会先检查是否存在缓存,如果没有就会先向根域名服务器发起请求,获得负责的顶级域名服务器的地址后,再向顶级域名服务器请求,然后获得负责的权威域名服务器的地址后,再向权威域名服务器发起请求,最终获得域名的 IP 地址后,本地 DNS 服务器再将这个 IP 地址返回给请求的用户。用户向本地 DNS 服务器发起请求属于递归请求,本地 DNS 服务器向各级域名服务器发起请求属于迭代请求。获取MAC地址
: 当浏览器得到 IP 地址后,数据传输还需要知道目的主机 MAC 地址,因为应用层下发数据给传输层,TCP 协议会指定源端口号和目的端口号,然后下发给网络层。网络层会将本机地址作为源地址,获取的 IP 地址作为目的地址。然后将下发给数据链路层,数据链路层的发送需要加入通信双方的 MAC 地址,本机的 MAC 地址作为源 MAC 地址,目的 MAC 地址需要分情况处理。通过将 IP 地址与本机的子网掩码相与,可以判断是否与请求主机在同一个子网里,如果在同一个子网里,可以使用 APR 协议获取到目的主机的 MAC 地址,如果不在一个子网里,那么请求应该转发给网关,由它代为转发,此时同样可以通过 ARP 协议来获取网关的 MAC 地址,此时目的主机的 MAC 地址应该为网关的地址。TCP三次握手
: 下面是TCP 建立连接
的三次握手的过程,首先客户端向服务器发送一个 SYN 连接请求报文段和一个随机序号,服务端接收到请求后向服务器端发送一个 SYN ACK报文段,确认连接请求,并且也向客户端发送一个随机序号。客户端接收服务器的确认应答后,进入连接建立的状态,同时向服务器也发送一个ACK 确认报文段,服务器端接收到确认后,也进入连接建立状态,此时双方的连接就建立起来了。HTTPS握手
: 如果使用的是 HTTPS 协议,在通信前还存在 TLS 的一个四次握手的过程。首先由客户端向服务器端发送使用的协议的版本号、一个随机数和可以使用的加密方法。服务器端收到后,确认加密的方法,也向客户端发送一个随机数和自己的数字证书。客户端收到后,首先检查数字证书是否有效,如果有效,则再生成一个随机数,并使用证书中的公钥对随机数加密,然后发送给服务器端,并且还会提供一个前面所有内容的 hash 值供服务器端检验。服务器端接收后,使用自己的私钥对数据解密,同时向客户端发送一个前面所有内容的 hash 值供客户端检验。这个时候双方都有了三个随机数,按照之前所约定的加密方法,使用这三个随机数生成一把秘钥,以后双方通信前,就使用这个秘钥对数据进行加密后再传输。服端的的亲求处理
: 当页面请求发送到服务器端后,服务器端会返回一个 html 文件作为响应,浏览器接收到响应后,开始对 html 文件进行解析,开始页面的渲染过程。页面渲染
: 浏览器首先会根据 html 文件构建 DOM 树,根据解析到的 css 文件构建 CSSOM 树,如果遇到 script 标签,则判端是否含有 defer 或者 async 属性,要不然 script 的加载和执行会造成页面的渲染的阻塞。当 DOM 树和 CSSOM 树建立好后,根据它们来构建渲染树。渲染树构建好后,会根据渲染树来进行布局。布局完成后,最后使用浏览器的 UI 接口对页面进行绘制。这个时候整个页面就显示出来了。TCP四次挥手
: 最后一步是 TCP 断开连接的四次挥手过程。若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。客户端收到释放请求后,向服务端发送确认应答,此时客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有服务端的重发请求的话,就进入 CLOSED 状态。当服务端收到确认应答后,也便进入 CLOSED 状态。
11. 浏览器缓存的优先级
答案
浏览器缓存的优先级主要遵循以下顺序:
Service Worker 缓存
:由于其可以完全控制网络请求,因此具有最高的优先级,即使是强制缓存也可以被它所覆盖。Service Worker是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。但请注意,由于Service Worker中涉及到请求拦截,所以必须使用HTTPS协议来保障安全。Memory Cache(内存缓存)
:这是内存中的缓存,主要包含的是当前页面中已经抓取到的资源,如样式、脚本、图片等。当我们访问过页面以后,再次刷新页面,可以发现很多数据都来自于内存缓存。HTTP Cache(HTTP缓存)
:- 强制缓存:在有效时间内,不会向服务器发送请求,直接从缓存中读取资源。控制强制缓存的字段分别是
Expires
和Cache-Control
,其中Cache-Control的优先级高于Expires。 - 协商缓存:当强制缓存失效后,浏览器会携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存。控制协商缓存的字段有
Last-Modified
/If-Modified-Since
和Etag/If-None-Match
。
- 强制缓存:在有效时间内,不会向服务器发送请求,直接从缓存中读取资源。控制强制缓存的字段分别是
Disk Cache(磁盘缓存)
:存储在硬盘中的缓存,读取速度较慢,但胜在容量和存储时效性上。Push Cache(推送缓存)
:这是HTTP/2中的内容,当以上四种缓存都没有命中时,它才会被使用。
12. 为什么会存在跨域及常见跨域的解决办法?
答案
跨域问题的存在主要是因为浏览器的同源策略限制。同源策略是浏览器的一种安全机制,旨在防止一个域的脚本与另一个域的内容进行交互,以保护用户免受诸如跨站脚本攻击(XSS)和跨站请求伪造(CSRF)等安全威胁。所谓同源,指的是两个页面具有相同的协议(如http或https)
、主机(域名或IP地址)
和端口
号。当这三个条件中任何一个不匹配时,就会触发跨域问题。
JSONP
:利用标签不受同源策略限制的特性,通过动态插入标签来请求不同源的数据。JSONP只支持GET请求,并且需要在服务器端进行相应的配合。CORS(跨域资源共享)
:CORS 是一种 W3C 规范,它定义了一种浏览器和服务器交互的方式来确定是否允许跨源请求。通过服务器端设置相应的HTTP头部信息,如Access-Control-Allow-Origin,来允许跨域请求。CORS 支持各种HTTP请求方法,并且更加灵活和安全。代理服务器
:通过搭建一个代理服务器来转发请求,使得前端可以通过代理服务器来间接访问不同源的资源。这样,前端请求实际上是发往同源的代理服务器,再由代理服务器去请求不同源的资源。(前端proxy代理、nginx)使用window.postMessage
:window.postMessage是HTML5引入的一个新的API,允许来自不同源的脚本进行通信。通过监听window对象的'message'事件,可以接收其他窗口发送过来的消息。设置document.domain
:如果两个页面属于同一个顶级域名下的不同子域名,可以通过设置document.domain为相同的顶级域名来实现跨域。但是,这种方式存在限制,并且可能引入其他安全风险。
13 HTTP 优、缺点
答案
HTTP 是超文本传输协议,它定义了客户端和服务器之间交换报文的格式和方式,默认使用 80 端口。它使用 TCP 作为传输层协议,保证了数据传输的可靠性。
HTTP协议具有以下优点:
- 支持客户端/服务器模式
无连接
:无连接就是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接,采用这种方式可以节省传输时间。无状态
:HTTP 协议是无状态协议,这里的状态是指通信过程的上下文信息。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能会导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就比较快。灵活
:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记简单快速
:客户向服务器请求服务时,只需传送请求方法和路径。由于 HTTP 协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
HTTP协议具有以下缺点:
- 无状态: HTTP 是一个无状态的协议,HTTP 服务器不会保存关于客户的任何信息。
- 明文传输: 协议中的报文使用的是文本形式,这就直接暴露给外界,不安全。
- 不安全:通信使用明文(不加密),内容可能会被窃听;不验证通信方的身份,因此有可能遭遇伪装;无法证明报文的完整性,所以有可能已遭篡改;
14. 说一下HTTP 3.0
答案
HTTP/3基于UDP协议实现了类似于TCP的多路复用数据流、传输可靠性等功能,这套功能被称为QUIC协议。
流量控制、传输可靠性功能
:QUIC在UDP的基础上增加了一层来保证数据传输可靠性,它提供了数据包重传、拥塞控制、以及其他一些TCP中的特性。集成TLS加密功能
:目前QUIC使用TLS1.3,减少了握手所花费的RTT数。多路复用
:同一物理连接上可以有多个独立的逻辑数据流,实现了数据流的单独传输,解决了TCP的队头阻塞问题。快速握手
:由于基于UDP,可以实现使用0 ~ 1个RTT来建立连接。
15. URL有哪些组成部分
答案
协议部分
:该URL的协议部分为“http:”,这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的“//”为分隔符;域名部分
:该URL的域名部分为“www.aspxfans.com”。一个URL中,也可以使用IP地址作为域名使用端口部分
:跟在域名后面的是端口,域名和端口之间使用“:”作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口(HTTP协议默认端口是80,HTTPS协议默认端口是443);虚拟目录部分
:从域名后的第一个“/”开始到最后一个“/”为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是“/news/”;文件名部分
:从域名后的最后一个“/”开始到“?”为止,是文件名部分,如果没有“?”,则是从域名后的最后一个“/”开始到“#”为止,是文件部分,如果没有“?”和“#”,那么从域名后的最后一个“/”开始到结束,都是文件名部分。本例中的文件名是“index.asp”。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名;锚部分
:从“#”开始到最后,都是锚部分。本例中的锚部分是“name”。锚部分也不是一个URL必须的部分;参数部分
:从“?”开始到“#”为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为“boardID=5&ID=24618&page=1”。参数可以允许有多个参数,参数与参数之间用“&”作为分隔符。
16 HTTPS的优缺点
答案
优点:
- 使用HTTPS协议可以认证用户和服务器,确保数据发送到正确的客户端和服务器;
- 使用HTTPS协议可以进行加密传输、身份认证,通信更加安全,防止数据在传输过程中被窃取、修改,确保数据安全性;
- HTTPS是现行架构下最安全的解决方案,虽然不是绝对的安全,但是大幅增加了中间人攻击的成本;
缺点:
- HTTPS需要做服务器和客户端双方的加密个解密处理,耗费更多服务器资源,过程复杂;
- HTTPS协议握手阶段比较费时,增加页面的加载时间;
- SSL证书是收费的,功能越强大的证书费用越高;
- HTTPS连接服务器端资源占用高很多,支持访客稍多的网站需要投入更大的成本;
- SSL证书需要绑定IP,不能再同一个IP上绑定多个域名
17 HTTPS是如何保证安全的?
答案
先来了解两个概念:
对称加密
:即通信的双⽅都使⽤同⼀个秘钥进⾏加解密,对称加密虽然很简单性能也好,但是⽆法解决⾸次把秘钥发给对⽅的问题,很容易被⿊客拦截秘钥。
⾮对称加密
:
- 私钥 + 公钥= 密钥对。
- 即⽤私钥加密的数据,只有对应的公钥才能解密,⽤公钥加密的数据,只有对应的私钥才能解密。
- 因为通信双⽅的⼿⾥都有⼀套⾃⼰的密钥对,通信之前双⽅会先把⾃⼰的公钥都先发给对⽅。
- 然后对⽅再拿着这个公钥来加密数据响应给对⽅,等到到了对⽅那⾥,对⽅再⽤⾃⼰的私钥进⾏解密。
⾮对称加密虽然安全性更⾼,但是带来的问题就是速度很慢,影响性能。
解决方案:
- 结合两种加密⽅式,将对称加密的密钥使⽤⾮对称加密的公钥进⾏加密,然后发送出去,接收⽅使⽤私钥进⾏解密得到对称加密的密钥,然后双⽅可以使⽤对称加密来进⾏沟通。
- 此时⼜带来⼀个问题,中间⼈问题:如果此时在客户端和服务器之间存在⼀个中间⼈,这个中间⼈只需要把原本双⽅通信互发的公钥,换成⾃⼰的公钥,这样中间⼈就可以轻松解密通信双⽅所发送的所有数据。
- 所以这个时候需要⼀个安全的第三⽅颁发证书(CA),证明身份的身份,防⽌被中间⼈攻击。 证书中包括:签发者、证书⽤途、使⽤者公钥、使⽤者私钥、使⽤者的HASH算法、证书到期时间等。
- 但是问题来了,如果中间⼈篡改了证书,那么身份证明是不是就⽆效了?这个证明就⽩买了,这个时候需要⼀个新的技术,数字签名。
- 数字签名就是⽤CA⾃带的HASH算法对证书的内容进⾏HASH得到⼀个摘要,再⽤CA的私钥加密,最终组成数字签名。当别⼈把他的证书发过来的时候,我再⽤同样的Hash算法,再次⽣成消息摘要,然后⽤CA的公钥对数字签名解密,得到CA创建的消息摘要,两者⼀⽐,就知道中间有没有被⼈篡改了。这个时候就能最⼤程度保证通信的安全了。
18. DNS 协议是什么
答案
概念
: DNS 是域名系统
(Domain Name System) 的缩写,提供的是一种主机名到 IP 地址的转换服务
,就是我们常说的域名系统。它是一个由分层的 DNS 服务器组成的分布式数据库,是定义了主机如何查询这个分布式数据库的方式的应用层协议。能够使人更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。
作用
: 将域名解析为IP地址,客户端向DNS服务器(DNS服务器有自己的IP地址)发送域名查询请求,DNS服务器告知客户机Web服务器的 IP 地址。 :::
19. DNS同时使用的 TCP和UDP协议
答案
- 在区域传输的时候使用TCP协议:
- 辅域名服务器会定时(一般3小时)向主域名服务器进行查询以便了解数据是否有变动。如有变动,会执行一次区域传送,进行数据同步。区域传送使用TCP而不是UDP,因为数据同步传送的数据量比一个请求应答的数据量要多得多。
- TCP是一种可靠连接,保证了数据的准确性。
- 在域名解析的时候使用UDP协议:
- 客户端向DNS服务器查询域名,一般返回的内容都不超过512字节,用UDP传输即可。不用经过三次握手,这样DNS服务器负载更低,响应更快。理论上说,客户端也可以指定向DNS服务器查询时用TCP,但事实上,很多DNS服务器进行配置的时候,仅支持UDP查询包。
20. DNS完整的查询过程
答案
DNS服务器解析域名的过程:
- 首先会在浏览器的缓存中查找对应的IP地址,如果查找到直接返回,若找不到继续下一步
- 将请求发送给本地DNS服务器,在本地域名服务器缓存中查询,如果查找到,就直接将查找结果返回,若找不到继续下一步
- 本地DNS服务器向根域名服务器发送请求,根域名服务器会返回一个所查询域的顶级域名服务器地址
- 本地DNS服务器向顶级域名服务器发送请求,接受请求的服务器查询自己的缓存,如果有记录,就返回查询结果,如果没有就返回相关的下一级的权威域名服务器的地址
- 本地DNS服务器向权威域名服务器发送请求,域名服务器返回对应的结果
- 本地DNS服务器将返回结果保存在缓存中,便于下次使用
- 本地DNS服务器将返回结果返回给浏览器
比如要查询 www.baidu.com 的 IP 地址,首先会在浏览器的缓存中查找是否有该域名的缓存,如果不存在就将请求发送到本地的 DNS 服务器中,本地DNS服务器会判断是否存在该域名的缓存,如果不存在,则向根域名服务器发送一个请求,根域名服务器返回负责 .com 的顶级域名服务器的 IP 地址的列表。然后本地 DNS 服务器再向其中一个负责 .com 的顶级域名服务器发送一个请求,负责 .com 的顶级域名服务器返回负责 .baidu 的权威域名服务器的 IP 地址列表。然后本地 DNS 服务器再向其中一个权威域名服务器发送一个请求,最后权威域名服务器返回一个对应的主机名的 IP 地址列表。
21. DNS 迭代查询与递归查询
答案
DNS解析是一个包含迭代查询和递归查询的过程。
递归查询
:指的是查询请求发出后,域名服务器代为向下一级域名服务器发出请求,最后向用户返回查询的最终结果。使用递归 查询,用户只需要发出一次查询请求。
迭代查询
:指的是查询请求后,域名服务器返回单次查询的结果。下一级的查询由用户自己请求。使用迭代查询,用户需要发出 多次的查询请求。
一般我们向本地 DNS 服务器发送请求的方式就是递归查询,因为我们只需要发出一次请求,然后本地 DNS 服务器返回给我 们最终的请求结果。而本地 DNS 服务器向其他域名服务器请求的过程是迭代查询的过程,因为每一次域名服务器只返回单次 查询的结果,下一级的查询由本地 DNS 服务器自己进行。
22. 网络模型 -- OSI七层模型
答案
ISO为了更好的使网络应用更为普及,推出了OSI参考模型。
应用层
:
- OSI参考模型中最靠近用户的一层,是为计算机用户提供应用接口,也为用户直接提供各种网络服务。我们常见应用层的网络服务协议有:HTTP,HTTPS,FTP,POP3、SMTP等。
- 在客户端与服务器中经常会有数据的请求,这个时候就是会用到http(hyper text transfer protocol)(超文本传输协议)或者https.在后端设计数据接口时,我们常常使用到这个协议。
- FTP是文件传输协议,在开发过程中,个人并没有涉及到,但是我想,在一些资源网站,比如百度网盘``迅雷应该是基于此协议的。
- SMTP是simple mail transfer protocol(简单邮件传输协议)。在一个项目中,在用户邮箱验证码登录的功能时,使用到了这个协议。
表示层
:
- 表示层提供各种用于应用层数据的编码和转换功能,确保一个系统的应用层发送的数据能被另一个系统的应用层识别。如果必要,该层可提供一种标准表示形式,用于将计算机内部的多种数据格式转换成通信中采用的标准表示形式。数据压缩和加密也是表示层可提供的转换功能之一。
- 在项目开发中,为了方便数据传输,可以使用base64对数据进行编解码。如果按功能来划分,base64应该是工作在表示层。
会话层
:
- 会话层就是负责建立、管理和终止表示层实体之间的通信会话。该层的通信由不同设备中的应用程序之间的服务请求和响应组成。
传输层
:
- 传输层建立了主机端到端的链接,传输层的作用是为上层协议提供端到端的可靠和透明的数据传输服务,包括处理差错控制和流量控制等问题。该层向高层屏蔽了下层数据通信的细节,使高层用户看到的只是在两个传输实体间的一条主机到主机的、可由用户控制和设定的、可靠的数据通路。我们通常说的,TCP UDP就是在这一层。端口号既是这里的“端”。
网络层
:
- 本层通过IP寻址来建立两个节点之间的连接,为源端的运输层送来的分组,选择合适的路由和交换节点,正确无误地按照地址传送给目的端的运输层。就是通常说的IP层。这一层就是我们经常说的IP协议层。IP协议是Internet的基础。我们可以这样理解,网络层规定了数据包的传输路线,而传输层则规定了数据包的传输方式。
数据链路层
:
- 将比特组合成字节,再将字节组合成帧,使用链路层地址 (以太网使用MAC地址)来访问介质,并进行差错检测。 网络层与数据链路层的对比,通过上面的描述,我们或许可以这样理解,网络层是规划了数据包的传输路线,而数据链路层就是传输路线。不过,在数据链路层上还增加了差错控制的功能。
物理层
:
- 实际最终信号的传输是通过物理层实现的。通过物理介质传输比特流。规定了电平、速度和电缆针脚。常用设备有(各种物理设备)集线器、中继器、调制解调器、网线、双绞线、同轴电缆。这些都是物理层的传输介质。
OSI七层模型通信特点
:对等通信 对等通信,为了使数据分组从源传送到目的地,源端OSI模型的每一层都必须与目的端的对等层进行通信,这种通信方式称为对等层通信。在每一层通信过程中,使用本层自己协议进行通信。
23. TCP/IP五层协议
答案
应用层 (application layer)
:直接为应用进程提供服务。应用层协议定义的是应用进程间通讯和交互的规则,不同的应用有着不同的应用层协议,如 HTTP协议(万维网服务)、FTP协议(文件传输)、SMTP协议(电子邮件)、DNS(域名查询)等。 传输层 (transport layer)
:有时也译为运输层,它负责为两台主机中的进程提供通信服务。该层主要有以下两种协议:
传输控制协议 (Transmission Control Protocol,TCP):提供面向连接的、可靠的数据传输服务,数据传输的基本单位是报文段(segment);
用户数据报协议 (User Datagram Protocol,UDP):提供无连接的、尽最大努力的数据传输服务,但不保证数据传输的可靠性,数据传输的基本单位是用户数据报。
网络层 (internet layer)
:有时也译为网际层,它负责为两台主机提供通信服务,并通过选择合适的路由将数据传递到目标主机。 数据链路层 (data link layer)
:负责将网络层交下来的 IP 数据报封装成帧,并在链路的两个相邻节点间传送帧,每一帧都包含数据和必要的控制信息(如同步信息、地址信息、差错控制等)。 物理层 (physical Layer)
:确保数据可以在各种物理媒介上进行传输,为数据的传输提供可靠的环境。
TCP/IP模型比OSI模型更加简洁,它把应用层/表示层/会话层
全部整合为了应用层
。
24. TCP 和 UDP的概念及特点
答案
TCP 和 UDP都是传输层协议,他们都属于TCP/IP协议族:
UDP:
UDP的全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。
- 面向无连接 首先 UDP 是不需要和 TCP一样在发送数据前进行三次握手建立连接的,想发数据就可以开始发送了。并且也只是数据报文的搬运工,不会对数据报文进行任何拆分和拼接操作。 具体来说就是:
在发送端,应用层将数据传递给传输层的 UDP 协议,UDP 只会给数据增加一个 UDP 头标识下是 UDP 协议,然后就传递给网络层了
在接收端,网络层将数据传递给传输层,UDP 只去除 IP 报文头就传递给应用层,不会任何拼接操作
- 有单播,多播,广播的功能 UDP 不止支持一对一的传输方式,同样支持一对多,多对多,多对一的方式,也就是说 UDP 提供了单播,多播,广播的功能。
- 面向报文 发送方的UDP对应用程序交下来的报文,在添加首部后就向下交付IP层。UDP对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。因此,应用程序必须选择合适大小的报文
- 不可靠性 首先不可靠性体现在无连接上,通信都不需要建立连接,想发就发,这样的情况肯定不可靠。 并且收到什么数据就传递什么数据,并且也不会备份数据,发送数据也不会关心对方是否已经正确接收到数据了。 再者网络环境时好时坏,但是 UDP 因为没有拥塞控制,一直会以恒定的速度发送数据。即使网络条件不好,也不会对发送速率进行调整。这样实现的弊端就是在网络条件不好的情况下可能会导致丢包,但是优点也很明显,在某些实时性要求高的场景(比如电话会议)就需要使用 UDP 而不是 TCP。
- 头部开销小,传输数据报文时是很高效的。UDP 头部包含了以下几个数据:
两个十六位的端口号,分别为源端口(可选字段)和目标端口
整个数据报文的长度
整个数据报文的检验和(IPv4 可选字段),该字段用于发现头部信息和数据中的错误
TCP:
TCP的全称是传输控制协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP 是面向连接的、可靠的流协议(流就是指不间断的数据结构)。特点:
- 面向连接 面向连接,是指发送数据之前必须在两端建立连接。建立连接的方法是“三次握手”,这样能建立可靠的连接。建立连接,是为数据的可靠传输打下了基础。
- 仅支持单播传输 每条TCP传输连接只能有两个端点,只能进行点对点的数据传输,不支持多播和广播传输方式。
- 面向字节流 TCP不像UDP一样那样一个个报文独立地传输,而是在不保留报文边界的情况下以字节流方式进行传输。
- 可靠传输 对于可靠传输,判断丢包、误码靠的是TCP的段编号以及确认号。TCP为了保证报文传输的可靠,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的字节发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据(假设丢失了)将会被重传。
- 提供拥塞控制 当网络出现拥塞的时候,TCP能够减小向网络注入数据的速率和数量,缓解拥塞。
- 提供全双工通信 TCP允许通信双方的应用程序在任何时候都能发送数据,因为TCP连接的两端都设有缓存,用来临时存放双向通信的数据。当然,TCP可以立即发送一个数据段,也可以缓存一段时间以便一次发送更多的数据段(最大的数据段大小取决于MSS)
25. TCP 和 UDP 区别
答案
区别 | UDP | TCP |
---|---|---|
是否连接 | 无连接 | 面向连接 |
是否可靠 | 不可靠传输,不使用流量控制和拥塞控制 | 可靠传输(数据顺序和正确性),使用流量控制和拥塞控制 |
连接对象个数 | 支持一对一,一对多,多对一和多对多交互通信 | 只能是一对一通信 |
传输方式 | 面向报文 | 面向字节流 |
首部开销 | 首部开销小,仅8字节 | 首部最小20字节,最大60字节 |
适用场景 | 适用于实时应用,例如视频会议、直播 | 适用于要求可靠传输的应用,例如文件传输 |
26. TCP和UDP的使用场景
答案
TCP应用场景
: 效率要求相对低,但对准确性要求相对高的场景。因为传输中需要对数据确认、重发、排序等操作,相比之下效率没有UDP高。例如:文件传输(准确高要求高、但是速度可以相对慢)、接受邮件、远程登录。
UDP应用场景
: 效率要求相对高,对准确性要求相对低的场景。例如:QQ聊天、在线视频、网络语音电话(即时通讯,速度要求高,但是出现偶尔断续不是太大问题,并且此处完全不可以使用重发机制)、广播通信(广播、多播)。
27. UDP协议为什么不可靠?
答案
UDP在传输数据之前不需要先建立连接,远地主机的运输层在接收到UDP报文后,不需要确认,提供不可靠交付。总结就以下四点:
- 不保证消息交付:不确认,不重传,无超时
- 不保证交付顺序:不设置包序号,不重排,不会发生队首阻塞
- 不跟踪连接状态:不必建立连接或重启状态机
- 不进行拥塞控制:不内置客户端或网络反馈机制
28. TCP的重传机制
答案
由于TCP的下层网络(网络层)可能出现丢失、重复或失序的情况,TCP协议提供可靠数据传输服务。为保证数据传输的正确性,TCP会重传其认为已丢失(包括报文中的比特错误)的包。TCP使用两套独立的机制来完成重传,一是基于时间,二是基于确认信息。
TCP在发送一个数据之后,就开启一个定时器,若是在这个时间内没有收到发送数据的ACK确认报文,则对该报文进行重传,在达到一定次数还没有成功时放弃并发送一个复位信号。
29. TCP的拥塞控制机制
答案
TCP的拥塞控制机制主要是以下四种机制:
慢启动(慢开始)
- 在开始发送的时候设置cwnd = 1(cwnd指的是拥塞窗口)
- 思路:开始的时候不要发送大量数据,而是先测试一下网络的拥塞程度,由小到大增加拥塞窗口的大小。
- 为了防止cwnd增长过大引起网络拥塞,设置一个慢开始门限(ssthresh 状态变量):
当cnwd < ssthresh,使用慢开始算法
当cnwd = ssthresh,既可使用慢开始算法,也可以使用拥塞避免算法
当cnwd > ssthresh,使用拥塞避免算法
拥塞避免
- 拥塞避免未必能够完全避免拥塞,是说在拥塞避免阶段将拥塞窗口控制为按线性增长,使网络不容易出现阻塞。
- 思路: 让拥塞窗口cwnd缓慢的增大,即每经过一个返回时间RTT就把发送方的拥塞控制窗口加一
- 无论是在慢开始阶段还是在拥塞避免阶段,只要发送方判断网络出现拥塞,就把慢开始门限设置为出现拥塞时的发送窗口大小的一半。然后把拥塞窗口设置为1,执行慢开始算法。
其中,判断网络出现拥塞的根据就是没有收到确认,虽然没有收到确认可能是其他原因的分组丢失,但是因为无法判定,所以都当做拥塞来处理。
快速重传
- 快重传要求接收方在收到一个失序的报文段后就立即发出重复确认(为的是使发送方及早知道有报文段没有到达对方)。发送方只要连续收到三个重复确认就立即重传对方尚未收到的报文段,而不必继续等待设置的重传计时器时间到期。
- 由于不需要等待设置的重传计时器到期,能尽早重传未被确认的报文段,能提高整个网络的吞吐量
快速恢复
- 当发送方连续收到三个重复确认时,就执行“乘法减小”算法,把ssthresh门限减半。但是接下去并不执行慢开始算法。
- 考虑到如果网络出现拥塞的话就不会收到好几个重复的确认,所以发送方现在认为网络可能没有出现拥塞。所以此时不执行慢开始算法,而是将cwnd设置为ssthresh的大小,然后执行拥塞避免算法。
30. TCP的流量控制机制
答案
一般来说,流量控制就是为了让发送方发送数据的速度不要太快,要让接收方来得及接收。TCP采用大小可变的滑动窗口进行流量控制,窗口大小的单位是字节。这里说的窗口大小其实就是每次传输的数据大小。
- 当一个连接建立时,连接的每一端分配一个缓冲区来保存输入的数据,并将缓冲区的大小发送给另一端。
- 当数据到达时,接收方发送确认,其中包含了自己剩余的缓冲区大小。(剩余的缓冲区空间的大小被称为窗口,指出窗口大小的通知称为窗口通告 。接收方在发送的每一确认中都含有一个窗口通告。)
- 如果接收方应用程序读数据的速度能够与数据到达的速度一样快,接收方将在每一确认中发送一个正的窗口通告。
- 如果发送方操作的速度快于接收方,接收到的数据最终将充满接收方的缓冲区,导致接收方通告一个零窗口 。发送方收到一个零窗口通告时,必须停止发送,直到接收方重新通告一个正的窗口。
31. TCP的可靠传输机制
答案
TCP 的可靠传输机制是基于连续 ARQ 协议和滑动窗口协议的。
- TCP 协议在发送方维持了一个发送窗口,发送窗口以前的报文段是已经发送并确认了的报文段,发送窗口中包含了已经发送但 未确认的报文段和允许发送但还未发送的报文段,发送窗口以后的报文段是缓存中还不允许发送的报文段。当发送方向接收方发 送报文时,会依次发送窗口内的所有报文段,并且设置一个定时器,这个定时器可以理解为是最早发送但未收到确认的报文段。 如果在定时器的时间内收到某一个报文段的确认回答,则滑动窗口,将窗口的首部向后滑动到确认报文段的后一个位置,此时如 果还有已发送但没有确认的报文段,则重新设置定时器,如果没有了则关闭定时器。如果定时器超时,则重新发送所有已经发送 但还未收到确认的报文段,并将超时的间隔设置为以前的两倍。当发送方收到接收方的三个冗余的确认应答后,这是一种指示, 说明该报文段以后的报文段很有可能发生丢失了,那么发送方会启用快速重传的机制,就是当前定时器结束前,发送所有的已发 送但确认的报文段。
- 接收方使用的是累计确认的机制,对于所有按序到达的报文段,接收方返回一个报文段的肯定回答。如果收到了一个乱序的报文 段,那么接方会直接丢弃,并返回一个最近的按序到达的报文段的肯定回答。使用累计确认保证了返回的确认号之前的报文段都 已经按序到达了,所以发送窗口可以移动到已确认报文段的后面。
- 发送窗口的大小是变化的,它是由接收窗口剩余大小和网络中拥塞程度来决定的,TCP 就是通过控制发送窗口的长度来控制报文 段的发送速率。
- 但是 TCP 协议并不完全和滑动窗口协议相同,因为许多的 TCP 实现会将失序的报文段给缓存起来,并且发生重传时,只会重 传一个报文段,因此 TCP 协议的可靠传输机制更像是窗口滑动协议和选择重传协议的一个混合体。
32. TCP的三次握手和四次挥手
答案
三次握手
:
- 第一次握手: 客户端向服务端发送连接请求报文段。该报文段中包含自身的数据通讯初始序号。请求发送后,客户端便进入 SYN-SENT 状态。
- 第二次握手: 服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态。
- 第三次握手: 当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。
TCP 三次握手的建立连接的过程就是相互确认初始序号的过程,告诉对方,什么样序号的报文段能够被正确接收。 第三次握手的作用是客户端对服务器端的初始序号的确认。如果只使用两次握手,那么服务器就没有办法知道自己的序号是否 已被确认。同时这样也是为了防止失效的请求报文段被服务器接收,而出现错误的情况。
四次挥手
:
- 第一次挥手: 若客户端认为数据发送完成,则它需要向服务端发送连接释放请求。
- 第二次挥手:服务端收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明客户端到服务端的连接已经释放,不再接收客户端发的数据了。但是因为 TCP 连接是双向的,所以服务端仍旧可以发送数据给客户端。
- 第三次挥手:服务端如果此时还有没发完的数据会继续发送,完毕后会向客户端发送连接释放请求,然后服务端便进入 LAST-ACK 状态。
- 第四次挥手: 客户端收到释放请求后,向服务端发送确认应答,此时客户端进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有服务端的重发请求的话,就进入 CLOSED 状态。当服务端收到确认应答后,也便进入 CLOSED 状态。
TCP 使用四次挥手的原因是因为 TCP 的连接是全双工的,所以需要双方分别释放到对方的连接,单独一方的连接释放,只代 表不能再向对方发送数据,连接处于的是半释放的状态。
最后一次挥手中,客户端会等待一段时间再关闭的原因,是为了防止发送给服务器的确认报文段丢失或者出错,从而导致服务器 端不能正常关闭。
33. TCP粘包是怎么回事
答案
默认情况下, TCP 连接会启⽤延迟传送算法 (Nagle 算法), 在数据发送之前缓存他们. 如果短时间有多个数据发送, 会缓冲到⼀起作⼀次发送 (缓冲⼤⼩⻅ socket.bufferSize ), 这样可以减少 IO 消耗提⾼性能.
如果是传输⽂件的话, 那么根本不⽤处理粘包的问题, 来⼀个包拼⼀个包就好了。但是如果是多条消息, 或者是别的⽤途的数据那么就需要处理粘包.
示例:
连续调⽤两次 send 分别发送两段数据 data1 和 data2, 在接收端有以下⼏种常⻅的情况:
A. 先接收到 data1, 然后接收到 data2
B. 先接收到 data1 的部分数据, 然后接收到 data1 余下的部分以及 data2 的全部
C. 先接收到了 data1 的全部数据和 data2 的部分数据, 然后接收到了 data2 的余下的数据
D. ⼀次性接收到了 data1 和 data2 的全部数据
其中的 BCD 就是我们常⻅的粘包的情况. ⽽对于处理粘包的问题, 常⻅的解决⽅案有:
多次发送之前间隔⼀个等待时间
:只需要等上⼀段时间再进⾏下⼀次 send 就好, 适⽤于交互频率特别低的场景. 缺点也很明显, 对于⽐较频繁的场景⽽⾔传输效率实在太低,不过⼏乎不⽤做什么处理.关闭 Nagle 算法
:关闭 Nagle 算法, 在 Node.js 中你可以通过 socket.setNoDelay() ⽅法来关闭 Nagle 算法, 让每⼀次 send 都不缓冲直接发送。该⽅法⽐较适⽤于每次发送的数据都⽐较⼤ (但不是⽂件那么⼤), 并且频率不是特别⾼的场景。如果是每次发送的数据量⽐较⼩, 并且频率特别⾼的, 关闭 Nagle 纯属⾃废武功。另外, 该⽅法不适⽤于⽹络较差的情况, 因为 Nagle 算法是在服务端进⾏的包合并情况, 但是如果短时间内客户端的⽹络情况不好, 或者应⽤层由于某些原因不能及时将 TCP 的数据 recv, 就会造成多个包在客户端缓冲从⽽粘包的情况。 (如果是在稳定的机房内部通信那么这个概率是⽐较⼩可以选择忽略的)进⾏封包/拆包
: 封包/拆包是⽬前业内常⻅的解决⽅案了。即给每个数据包在发送之前, 于其前/后放⼀些有特征的数据, 然后收到数据的时 候根据特征数据分割出来各个数据包。
34. 为什么udp不会粘包
答案
- TCP协议是⾯向流的协议,UDP是⾯向消息的协议。UDP段都是⼀条消息,应⽤程序必须以消息为单位提取数据,不能⼀次提取任意字节的数据
- UDP具有保护消息边界,在每个UDP包中就有了消息头(消息来源地址,端⼝等信息),这样对于接收端来说就容易进⾏区分处理了。传输协议把数据当作⼀条独⽴的消息在⽹上传输,接收端只能接收独⽴的消息。接收端⼀次只能接收发送端发出的⼀个数据包,如果⼀次接受数据的⼤⼩⼩于发送端⼀次发送的数据⼤⼩,就会丢失⼀部分数据,即使丢失,接受端也不会分两次去接收。
35.即时通讯的实现:短轮询、长轮询、SSE 和 WebSocket 间的区别?
答案
短轮询和长轮询的目的都是用于实现客户端和服务器端的一个即时通讯。
短轮询的基本思路
: 浏览器每隔一段时间向浏览器发送 http 请求,服务器端在收到请求后,不论是否有数据更新,都直接进行响应。这种方式实现的即时通信,本质上还是浏览器发送请求,服务器接受请求的一个过程,通过让客户端不断的进行请求,使得客户端能够模拟实时地收到服务器端的数据的变化。这种方式的优点是比较简单,易于理解。缺点是这种方式由于需要不断的建立 http 连接,严重浪费了服务器端和客户端的资源。当用户增加时,服务器端的压力就会变大,这是很不合理的。长轮询的基本思路
: 首先由客户端向服务器发起请求,当服务器收到客户端发来的请求后,服务器端不会直接进行响应,而是先将这个请求挂起,然后判断服务器端数据是否有更新。如果有更新,则进行响应,如果一直没有数据,则到达一定的时间限制才返回。客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。长轮询和短轮询比起来,它的优点是明显减少了很多不必要的 http 请求次数,相比之下节约了资源。长轮询的缺点在于,连接挂起也会导致资源的浪费。SSE 的基本思想
: 服务器使用流信息向服务器推送信息。严格地说,http 协议无法做到服务器主动推送信息。但是,有一种变通方法,就是服务器向客户端声明,接下来要发送的是流信息。也就是说,发送的不是一次性的数据包,而是一个数据流,会连续不断地发送过来。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。SSE 就是利用这种机制,使用流信息向浏览器推送信息。它基于 http 协议,目前除了 IE/Edge,其他浏览器都支持。它相对于前面两种方式来说,不需要建立过多的 http 请求,相比之下节约了资源。WebSocket
: 是 HTML5 定义的一个新协议议,与传统的 http 协议不同,该协议允许由服务器主动的向客户端推送信息。使用 WebSocket 协议的缺点是在服务器端的配置比较复杂。WebSocket 是一个全双工的协议,也就是通信双方是平等的,可以相互发送消息,而 SSE 的方式是单向通信的,只能由服务器端向客户端推送信息,如果客户端需要发送信息就是属于下一个 http 请求了。
上面的四个通信协议,前三个都是基于HTTP协议的。对于这四种即使通信协议,从性能的角度来看: WebSocket > 长连接(SEE) > 长轮询 > 短轮询,但是,我们如果考虑浏览器的兼容性问题,顺序就恰恰相反了:短轮询 > 长轮询 > 长连接(SEE) > WebSocket。所以,还是要根据具体的使用场景来判断使用哪种方式。