- 2024前端年末备战面试题——HTML篇
- 2024前端年末备战面试题——CSS篇
- 2024前端年末备战面试题——浏览器篇
- 2024前端年末备战面试题——JavaScript篇
- 2024前端年末备战面试题——框架篇(Vue)
- 2024前端年末备战面试题——构建工具与git
网络篇
本文是本人根据一些书籍或者网上一些其他朋友的文章以及自己的理解,整理归纳出来的一篇网络协议方面的面试题,其中不免有许多漏掉的问题或是答案,发现错误的或者是有什么问题需要补充的朋友们,可以在评论区留言,大家虚心交流,一起进步。
1. HTTP协议
(1)HTTP是什么?
大家都知道HTTP就是超文本传输协议
,具体指的是什么呢?
超文本
:,就是“超越了普通的文本”
,它是文字、图片、音视频等内容的结合体
,并且含有超链接
,能从一个超文本
跳到另一个超文本
,形成复杂的非线性、网状的结构关系
,譬如我们的HTML
,它就是超文本标记语言
;传输
:代表了从某一处
传递信息到另一处
;协议
:代表了某种规范
,使用这个东西的双方,都应该遵循的规范;
总的来说,HTTP
就是在计算机的世界里,为两点之间传输文字、图片、音视频等超文本数据的一种约定和规范
。
(2)HTTP协议的特点
HTTP
拥有无状态
、无连接
、可靠传输
、灵活可拓展
的特点
无状态
:无状态指的是通过HTTP协议传输数据的双方,永远都是处于一种无知
的状态,连接之前两者互不知情,传输完数据之后不会保存
双方的任何信息
,下次再次连接双方还是互不认识
;无连接
:无连接指的是通过HTTP协议传输信息的双方,建立连接之后,传输完数据会断开连接
,不会保持连接,下次想要传输信息,需要重新建立连接
;(HTTP1.1之后可以保持长连接)可靠传输
:之所以说它是可靠传输的,是因为HTTP是基于TCP/IP
的,而TCP本身就是可靠安全的传输协议
;灵活可拓展
:在HTTP发展的过程中,逐渐增加了请求方法
、状态码
等特性,并且传输内容也不仅限于文本
或HTML
等,而是能够通过设置Content-Type
来传输图片
、音视频
等数据;
2. HTTP报文由哪些组成
HTTP报文
分为请求报文
以及响应报文
;
(1)请求报文
请求报文
一共由请求行
、请求头
、空行
、请求体
四部分组成;
请求行
中包括了请求方法
、请求地址
、HTTP协议版本号
等信息;请求头
中包括了许多由key: value
(键值对)组成的请求附加信息
;空行
就是没有任何信息的空行
,协议中规定请求头和请求主体间必须用一个空行隔开,用来区分
请求头与请求体,因为请求头都是key:value
的格式,当解析遇到空行时,服务端就知道下一个不再是请求头部分,就该当作请求体来解析了;请求体
就是我们发起请求时的一些参数信息
,一般只有在非get
请求中才需要请求体
;
(2)响应报文
响应报文
一共由响应行(状态行)
、响应头
、空行
、响应体
四部分组成;
响应行
中包括了HTTP协议版本号
、请求状态码
、状态码的英文符号
;响应头
和请求头类似,都是以key: value
的形式存在,是响应返回的一些附加信息
;空行
的作用就是在响应头
和响应体
之间做区分用的;响应体
就是服务端真正想要返回给客户端的内容了;
3. HTTP的请求方法
(1)请求方法
HTTP1.0
有GET
、POST
、HEAD
三种请求方法;
HTTP1.1
新增了PUT
、DELETE
、OPTIONS
、TRACE
、CONNECT
五种请求方法;
GET
:发送一个请求来取得服务器上的某一资源;POST
:发送一个请求,并附加一些数据
,一般用来提交
、修改
某一资源;HEAD
:只获取响应结果的响应头
;PUT
:和POST相似
,一般用来提交
、修改
一些资源;DELETE
:一般用来删除
某些资源;OPTIONS
:一般作为CORS
的预检请求,查看是否可以跨域
;TRACE
:一般用来获取服务器收到的请求信息
,多用于诊断或测试
;CONNECT
:用于建立隧道连接,比如客户端和代理服务器
之间建立一条TCP连接,从而实现代理服务器的建立;
(2)GET和POST的区别
约定语义角度
:GET用来无副作用的请求资源
,理应幂等,即参数相同时
多次请求的结果不变
,而POST一般用来传递数据,进行新增、修改、删除
等操作;缓存角度
:GET请求会被浏览器自动缓存
,POST不会
被浏览器进行缓存
,如果想进行缓存,可以通过代理服务器
实现缓存;参数角度
:GET请求的参数会拼接在请求地址之后
,有长度限制,而POST请求的参数存放在请求体
,大小没有限制;安全角度
:由于GET和POST请求参数存放的位置不同,看似POST请求更加安全
,但是在抓包
的情况下,二者都差不多;回退和刷新角度
:GET请求可以直接进行回退和刷新
,不会
对用户和程序产生任何影响
;而 POST 请求如果直接回滚和刷新
将会把数据再次提交
;编码角度
:GET只能进行url编码
,参数的数据类型只接受ASCII字符
,而POST支持更多的编码类型
且不对数据类型限制;效率角度
:GET请求产生一个TCP数据包,而POST产生2个TCP数据包,首先发送header
部分,如果服务器响应100
, 然后发送body
部分,因此POST在效率上比GET要差一些;
(3)为什么GET请求有长度限制
从HTTP协议规范
层面说,规范没有
对URL的长度进行限制
,但是由于参数是拼接在URL之后的
,浏览器、服务器
的读取有限制;
(4)PUT和POST的区别
约定语义角度
:PUT遵循幂等性原则
,POST不遵循幂等性原则
,PUT通常表示的是新建
,而POST通常表示的是修改
;用途角度
:PUT和POST都可以
用来新增或修改某些数据;用法角度
:PUT一般用来全量
修改数据,把新文件/数据整体传递
给服务端,服务端直接更新数据,POST一般是传递部分数据
,服务端获取到参数后决定局部修改
或者全部修改
;
(5)OPTIONS请求的作用
一般在对非同域
的地址发送请求时,浏览器会先发送OPTIONS(预检)
请求,来查看服务端是否支持跨域请求
,如果不同意,就会停止发送请求,如果同意跨域,才会继续发送请求。
4. HTTP常见的请求头
HTTP协议
中规定了许多的头部字段,实现各种各样的功能,但是基本可以分成四大类:
通用字段
:响应头和请求头都可以出现;请求字段
:只会出现在请求头中,补充请求信息或额外的条件;响应字段
:只会出现在响应头中,补充响应报文的信息;实体字段
:实际上属于通用字段,但是专门描述body的额外信息;
常见的头
HOST
:属于请求字段
,是HTTP1.1中要求必须出现
的字段,如果没有该字段,就是一个错误的报文
,该字段告诉服务器该请求由哪个主机来处理
,值是一个域名
或者ip地址
;User-Agent
:属于请求字段
,它使用一个字符串
来描述发起HTTP请求的客户端,服务器可以根据它来返回最合适此浏览器显示的页面;Date
:属于通用字段
,但是通常出现在响应头
中,表示HTTP报文创建的时间
,客户端可以使用这个时间搭配其他字段决定缓存策略
;Server
:属于响应字段
,它告诉客户端正在使用提供Web服务的软件名称
和版本号
;Content-Length
:属于实体字段
,表示报文里请求体或响应体
的长度,服务器看到该字段,就知道后续有多少数据,直接进行接收;Accept
:属于请求字段
,浏览器能够处理的内容类型;Accept-Charset
:属于请求字段
,浏览器能够显示的字符集;Accept-Encoding
:属于请求字段
,浏览器能够处理的压缩编码;Accept-Language
:属于请求字段
,浏览器当前设置的语言;Connection
:属于通用字段
,浏览器与服务器之间连接的类型;Cookie
:属于请求字段
,当前页面设置的任何Cookie;Referer
:属于请求字段
,发出请求的页面的URL;Content-Type
:属于实体字段
,表示服务器返回数据类型的MIME类型;Expires
:属于实体字段
,表示缓存过期时间;Cache-Control
属于通用字段
,用于控制缓存策略;
Content-Type的格式
Content-Type的格式:Content-Type:type/subtype ;parameter
type
:主类型,任意的字符串,如果是*号代表所有;subtype
:子类型,任意的字符串,如果是*号代表所有,用“/”与主类型隔开;parameter
:可选参数,如charset,boundary等;
常见的Content-Type的值
application/x-www-form-urlencoded
:请求发送过程中会对数据进行序列化处理
,以键值对形式(key1=value1&key2=value2
)的方式发送到服务器,如果是中文或特殊字符如"/"、","、“:" 等会自动进行URL转码;multipart/form-data
:用于表单中进行文件上传
;application/json
:请求体内容是json格式
的字符串;
5. HTTP常见的状态码
-
状态码
是一个十进制数字
,以代码的形式表示服务器对请求的处理结果; -
目前
RFC标准
里规定的状态码是三位数
,取值范围为000~999
,标准里规定了41
种状态码,但是允许自行拓展
; -
RFC标准
将状态码分为五类
,用数字第一位
表示分类,标准里状态码的范围在100~599
;
(1)宽泛的状态码分类
1xx
:提示信息,表示目前是协议处理
的中间状态
,还有后续的操作;2xx
:表示成功,报文已经被成功接收
并且正确处理
;'3xx
:表示重定向,资源位置发生变动,需要客户端重新发起请求
;4xx
:表示客户端错误,请求报文有误
,服务端无法处理
;5xx
:表示服务端错误,服务器在处理请求时,内部发生了错误
;
(2)一些具体的状态码以及含义
100
:(客户端继续发送请求,这是临时响应
)这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成,忽略这个响应。服务器必须在请求完成后向客户端发送一个最终响应;101
:客户端使用Upgrade
头字段,要求在HTTP协议基础上改成其他协议继续通信,如果服务器同意变更,则返回101状态码,后续数据传输就改用新的协议;103
(Early Hints
):客户端应在服务端返回HTML
前开始预加载资源;200
:请求已成功
,请求所希望的响应头或数据体将随此响应返回;201
:请求已创建
,请求成功并且服务器创建了新的资源;202
:请求已接受
,服务器已经接受请求,但还没处理;203
:非授权信息
,服务器已成功处理了请求,但返回的信息可能来自另一来源;204
:无内容
,服务器成功处理请求,但没有返回任何内容;205
:重置内容
, 服务器成功处理了请求,但没有返回任何内容。与 204 响应不同
,此响应要求请求者重置文档视图(例如,清除表单内容以输入新内容);206
:处理部分请求
,服务器已经成功处理了部分请求,是断点续传
和分块下载
的基础;300
:多种选择
,针对请求,服务器可执行多种操作,服务器可根据请求者 (user agent) 选择一项操作,或提供操作列表供请求者选择;301
:永久重定向
,请求的网页已永久移动到新位置。服务器不会返回资源,而是会自动将请求者转到新的URL,需要告知客户端这个页面地址已经永久
变成新的了;302
:临时重定向
,服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求,不需要告知客户端这个页面地址改变了;303
:临时重定向
,将POST请求重定向,然后强制以GET方式发送请求;304
:缓存重定向
,意为资源未修改
,可以使用协商缓存的内容,因此也称为缓存重定向
;305
:使用代理
,请求者只能使用代理访问请求的网页,如果服务器返回此响应,表示请求者应使用代理;307
:临时重定向
,和302类似,但是如果原请求是POST
,重定向之后不能以GET
请求发出;308
:永久重定向
,和301类似,但是如果原请求是POST
,重定向之后不能以GET
请求发出;400
:请求语法错误
,服务器不理解;401
:未授权
,要求发起请求的用户进行身份验证,一般对于登录后的网页
,服务器才会做此响应;403
:拒绝
,服务器拒绝了请求;404
:资源不存在
,请求的资源不存在,服务器找不到;405
:方法禁用
,发起请求的方法不对;406
:不接受
,无法使用请求的内容特性响应请求的网页;500
:服务器内部错误
,服务器内部报错,无法响应请求;501
:尚未实施
,服务器还未具备完成请求的功能;502
:错误网关
,服务器作为网关或代理,从上游服务器收到无效响应;503
:服务不可用
,服务器目前处于不可用状态,比如在维护或超载了,但这只是暂时的;504
:网关超时
,服务器作为网关或代理,但是没有及时从上游服务器收到请求;505
:HTTP 版本不受支持
,服务器不支持请求中所用的 HTTP 协议版本;
(3)301、302、303、307、308之间的关系和区别
规范
302
、303
、307
都是临时重定向
,一开始只有302
这一个状态码,HTTP1.0规范规定:
如果原请求
不是GET或HEAD
,302状态码不能自动重定向
。
实现
但是许多浏览器在实现302状态码时,并没有严格遵守规范
,即使是POST请求
,也会自动进行重定向,并且大多数浏览器还会以GET请求
重新发起请求,导致原POST请求参数丢失
。
结果
为了应对这种情况,HTTP1.1的规范
中,新增了303
、307
、308
状态码。
303
状态码时,无论GET还是POST请求
,都会自动重定向
,并且强制以GET请求
重新发起请求;307
状态码时,和302基本一致,依旧只有GET和HEAD请求
可以自动重定向,但是不允许原POST请求以GET请求重新发起请求
;308
状态码时,和301基本一致,但是不允许原POST请求以GET请求重新发起请求
;
总结
- 303和307是HTTP1.1中对
302的拓展
; - 303就是302在浏览器中
真实的实现
方式; - 307是302在规范中
真正应该实现
的方式; - 307和303可以替代302,但302的保留是为了兼容之前的;
- 308除了不能将原POST请求以GET请求重新发出以外,其余都一样;
(4)详细说说103状态码
2022
年6
月Chrome 官方
宣布在chrome 103
版本对HTTP 103
状态码提供了支持;Chrome 官方
也宣布在chrome 106
版本对HTTP/2 Server Push
进行禁用;
-
正常情况下,我们需要
等待HTML页面的返回
后,才可以知道下一步需要去加载
哪些JS
、CSS
文件,这中间有一段的等待时间就被浪费掉了;这尤其在SSR
项目中尤为明显; -
HTTP 103
状态码可以返回一个初步的HTTP
响应,浏览器可以使用这些提示来预连接
,并在等待资源响应的同时请求子资源; -
它在
SSR
项目里面会非常有用;在SPA
项目里面,大部分的逻辑都在客户端,HTML很小
,这时候我们只需要用常规的preload
、preconnect
之类的手段就可以了;
(5) 103 状态码和HTTP2服务器推送的区别
- 使用
HTTP2服务器推送
时,很多资源其实浏览器第一次请求就已经缓存下来了,但是服务端推送
仍然会推送已缓存的资源
,会导致网络带宽浪费
;这是它的一个缺点,所以使用的人也较少; HTTP2
服务器推送是直接发送资源,而103
状态码只是向浏览器发送资源提示,浏览器可以控制是否需要这些资源,因为相同的资源可能已经在浏览器缓存过了;- 总的来说,
HTTP103 (Early Hints)
它能够解决网络带宽浪费
的问题,可以说是HTTP/2 Server Push
的升级版,不过目前还没有完全覆盖服务器推送的所有用例;
6. TCP、UDP
(1)TCP
TCP协议
是一种面向连接的
、可靠传输的
、基于字节流的
、全双工
传输层通信协议。
它拥有以下特点:
面向连接
使用TCP协议
之前,必须先进行TCP连接
,也就是我们常说的三次握手
,数据传输完毕之后,关闭已经建立的TCP连接
,也就是我们常说的四次挥手
,它的连接只能
有两个端点
,也就是说,它的连接是一对一的
。
全双工通信
全双工通信
指的就是通信双方都具有接收
和发送
信息的能力。
可靠传输
TCP协议
的连接是一对一的,且是全双工通信
,发送端会将数据分段,然后给每一段数据进行编号
,然后发出,当接收端收到数据
,并且返回确认消息(ACK应答报文)
,发送端接收到应答消息
之后,才会继续发送
下一段数据,如果没有收到确认消息
,就会重发这一段消息
。
比如有两个端点A
和B
进行了连接,A里有1,2,3三段数据要发送给B:
A
先发送1
数据,此时发送窗口还保留着a,b在后面排队;B
接收到了1
数据,将确认消息
发送给了A
,并且A
接收到了;A
继续开始发送2
数据......
正因为有了这种编号机制
和确认应答
机制,才不会导致数据混乱
或是数据丢失
,才保证了TCP协议传输的可靠性
。
基于字节流的
TCP
是将一条用户消息根据滑动窗口的字节大小,拆分成多个TCP
报文段(TCP将数据看作一连串字节流
);
滑动窗口
因为普通的发送
和应答
太浪费时间,一次只能发送一组数据
,等到这组数据的应答返回时,才能继续发送下一组
,因此滑动窗口
出现了,滑动窗口的出现就是允许一次发送多组数据
,然后返回一个ACK
就继续发送下一组
数据。
- 滑动窗口的大小是通过
TCP协议头部的“窗口大小” 字段
,来进行控制的; - 操作系统为了维护滑动窗口,开辟
发送缓冲区
,记录了哪些数据没有应答,应答之后才会从缓冲区删掉;
流量控制
接收端处理数据的速度是有限的
。如果发送端发送的速度太快
,导致接收缓冲区
占满(接收缓冲区包含了按序到达但尚未被应用程序读取的数据,不按序到达以及尚未进入接收窗口的数据。),这个时候如果发送端继续发送,就会造成丢包,继而引起丢包重传等等一系列连锁反应。流量控制
的目的就是让发送端可以根据接收端的实际接收能力
控制发送的数据量。
TCP
协议的头部信息中,有一个16位
字段的窗口大小,窗口大小的内容就是接收缓冲区的剩余大小,可以通过ACK报文将该字段告知发送端;- 接收端一旦发现自己的
缓冲区快满了
,就会将窗口大小设置成一个更小的值
通知给发送端; - 如果接收端
缓冲区满了
,就会将窗口设置为0
;这时发送方不再发送数据,但是需要定期发送一个窗口探测数据段
,使接收端把窗口大小告诉发送端;
拥塞控制
虽然TCP有了滑动窗口
这个功能,能够高效可靠
的发送大量的数据。但是如果在刚开始
阶段就发送大量的数据
,仍然可能引发问题,比如当前网络状态比较拥堵
,如果一开始就发送较多数据
,就会造成堆积。而拥塞控制
的出现,就是根据当前的网络状态
对发送数据进行限制。
拥塞控制
引入了拥塞窗口
的概念,它是发送端
维护的一个变量,根据网络拥塞情况
变大或变小,当发出的数据没有接到应答时
,会被发送端认为网络出现了拥塞
,就会减少拥塞窗口的值
,如果接收到了应答,就会增加拥塞窗口的值
,所以说最终发送端的发送量,是由拥塞窗口
和滑动窗口
的最小值进行决定的。
慢启动
:一开始不要
传输大量数据
,先试试水,如果网络状态还行,每次收到1个应答
,那就拥塞窗口大小+1
,下次发送n个数据,这时候拥塞窗口大小就增加n,这时,拥塞窗口呈指数级增长
,直到达到慢启动的阈值
,当拥塞窗口小于慢启动阈值时
,采用慢启动算法;拥塞避免
:当拥塞窗口大于等于慢启动阈值时
,采用拥塞避免,此时每次收到n个应答(n就是拥塞窗口的值)
,拥塞窗口大小增加1
,这时拥塞窗口呈线性级增长
;拥塞发生
:当发现网络拥塞
,也就是发送的数据无应答
时,说明发生了网络拥塞,这时候会将慢启动阈值设置为拥塞窗口的1/2
,然后拥塞窗口重置为1,重新启动慢启动算法;快速重传
:就是接收方在收到失序的报文后
立即发出一个重复的ACK
,如果只是1~2
个重复的(前一个包)ACK,说明只是短暂的延时造成的失序
,无需进行处理,如果发送三次
相同的的ACK,发送端就会认为包丢失了
,就会立即重传
对方尚未收到的报文段,而不用继续等待超时再重传;快速恢复
:快速恢复算法认为,发送端能收到3个确认报文,说明接收端接收情况还是可以的,网络情况还行,于是就重新发送丢失的报文
,并且继续执行避免拥塞的算法
,不需要使用慢启动
;
(2)UDP
UDP
是一个无连接的
、不可靠的
、面向报文
的传输层通信协议
;
它拥有以下特点:
无连接的
使用UDP协议
通信的双方,发送数据之前不需要进行连接
,发送数据后,也不需要断开连接
,减少了开销,正因为它是无连接的
,因此它可以支持1对多
;
不可靠的
UDP尽最大努力交付,但不保证可靠交付
、不保证数据的顺序
,即使发生丢包,也不会返回任何错误信息;
面向报文
UDP只是个搬运工,发送端发送的报文,UDP不会
进行拆分
、合并
,仅保留报文的边界,添加了首部之后
就交付给IP层;
没有拥塞控制
即使网络拥塞,UDP也不会降低传输效率
;
7. TCP和UDP的区别是什么,谁更好?
(1)区别
TCP
更加安全可靠,UDP
不可靠;TCP
只支持1对1,UDP
可支持1对多和1对1TCP
发送数据之前需要连接,UDP
则不需要,因此TCP效率不如
UDP;TCP
首部开销大,最小20
字节,最大60
字节,UDP
首部开销小,仅有8字节
;TCP
面向字节流,可将报文拆分成多段进行发送,而UDP
面向报文,不可拆分报文;TCP
拥有拥塞控制、流量控制等手段,而UDP
没有这些手段,不会降低发送效率;
(2)谁更好
TCP
和UDP
之间没有谁更好,TCP
更加可靠,而UDP
效率更高,特定的使用场景下
,它们都有各自的好处;
TCP
的优点在于它是安全可靠的
,因此在一些以安全为重的场景下,TCP无疑是最好的;
UDP
的优点在于它效率非常高
,因此在一些以效率为重的场景下,即使发生丢包也没什么太大影响的场景下,UDP的优势就会非常明显;
8. 流量控制和拥塞控制的区别是什么
流量控制
是根据接收端接收能力的大小
,对发送端的发送数量进行限制
;拥塞控制
是根据网络承载能力的大小
,对发送端的发送数量进行限制
;二者结合
,才是最终发送端发送的数量
,即取二者的最小值
;
9. 三次握手和四次挥手是什么
三次握手
是通信两端建立连接
的过程;四次挥手
是通信两端断开连接
的过程;
(1)三次握手的过程
- 发送端向接收端发送
SYN
报文,进行第一次握手; - 接收端接收到
SYN
报文,然后回复SYN
报文和ACK
报文给发送端,进行第二次握手; - 发送端接收到
SYN
和ACK
报文,然后继续发送SYN
报文给接收端,进行第三次握手;
(2)三次握手的意义
之所以进行三次握手
,是要确认发送端和接收端都有发送和接收的能力
;
第一次握手
,发送端进行发送,证明了发送端有发送能力
;- 接收端接收到了发送端发送的数据,知道了发送端拥有发送能力,但是接收端不知道
发送端是否有接收能力
,于是进行第二次握手
; - 发送端接收到了接收端返回的报文,知道了
接收端拥有接收和发送的能力
,但是我也应该让它知道我接收到了它的信息,于是又进行第三次握手
,再次发送报文给接收端,告知接收端,我接收到你的消息了,可以建立连接了;
(3)三次握手改成两次握手不行吗?
先说结论,不行!
我们从确认彼此收发能力
的角度看,两次握手
确实已经足够,比如在第二次握手之后,我们就可以进行连接,然后发送端就开始发送数据,接收端一看,你发来数据了,说明你收到我刚才给你的信息了,这不是也可以证明彼此都有收发信息的能力了吗?
但是我们看一下下面这个场景:
- 发送端发送了一个SYN报文,然后
发送端
因为某种原因宕机了
,而且这个报文被网络阻塞了
,接收端并没有收到
; - 过了一会,发送端
恢复正常
,然后又重新发了一个SYN报文,这时候,前一个SYN报文
被接收端先收到了,然后接收端返回了一个对应前一个报文的ACK
; - 发送端收到这个ACK,心想,不对啊,这不是我刚发出去的那一个啊;
三次握手
就是为了防止这种建立历史连接
的场景发生,在三次握手的情况下,接下来会发生如下操作:
- 发送端发现不对劲之后,就会发送一个
RST报文
; - 接收端收到发送端发送的
RST报文
就会意识到,原来我接收错了,于是就会释放连接,等待正确的SYN报文
;
而如果是两次握手
,在发送端接收到错误的ACK之后
就已经建立了连接,没有机会
通知接收端“你接收错了”。
如果新的SYN报文
在RST报文发送之前
就被接收端
收到了会怎么样呢?这时接收端还会将上一次的ACK报文发送给发送端
,发送端收到之后,还是会发送RST报文
给接收端;
(4)三次握手的过程中可以携带数据吗
第一次第二次不可以
,因为此时还没有建立连接,第三次握手是可以的
,因为第三次握手的时候发送端已经建立连接了
,它也知道接收端的收发
能力是正常的了,是可以携带数据的。
(5)四次挥手的过程
第一次挥手
,发送端发送FIN报文
给接收端;第二次挥手
,接收端回复ACK报文
,表明我收到了你要断开连接的请求;第三次挥手
,接收端发送FIN报文
给发送端;第四次挥手
,发送端发送ACK报文
给接收端,表明我收到了你断开连接的请求,然后发送端经过2MSL
之后断开连接,接收端收到发送端的ACK报文之后,立马断开连接;
(6)四次挥手的意义
因为TCP
是全双工通信
,不能单方面断开连接,因此必须双方都断开连接的情况下才能断开连接。
(7)四次挥手可以携带数据吗
第一次挥手
,发送端是要准备断开连接的,这时已经不允许发送端继续发送数据了;第二次挥手
,发送端只是不能发送数据,但还没有关闭接收数据的能力,接收端如果有没处理完的数据,还是可以继续发送给发送端的;第三次挥手
,接收端也打算断开连接,关闭自己发送数据的能力了,因此也是不能发送数据的;第四次挥手
,都不能进行发送数据了,准备断开连接了;
(8)四次挥手最终等待2MSL的原因是什么
RFC协议
规定了MSL
为2分钟,2MSL就是4分钟
。
假设这种情况,第四次挥手中
,发送端发送ACK
给接收端,这时候如果发生丢包
,接收端未接收
到发送端发送的ACK,那么接收端就会重新发送FIN
,请求断开。
而等待2MSL
就是为了应对这种情况,当发送端
又接收到接收端发送的FIN报文后
,会重新发送ACK报文
,并且再次等待2MSL;
10. TCP/IP协议是什么?
TCP/IP
是能够在多个不同网络间实现信息传输的协议簇
;TCP/IP协议
不只是有TCP和IP协议,像HTTP
、UDP
也属于其中的一种;- 主要是因为
TCP协议
和IP协议
最具代表性
,采用它们俩的名字来命名;
11. 单工通信、半双工通信、双工通信是什么
单工通信
就是指通信双方只有有一方发送数据
,另一方负责接收数据
;半双工通信
就是指通信双方都具有发送和接收数据的能力
,但是不能同时进行,比如A在发送数据时,B只能接收,不能发送;全双工通信
就是指双方都具有发送和接收数据的能力
,并且可以同时进行
;
12. HTTP的版本
HTTP版本有HTTP0.9
、HTTP1.0
、HTTP1.1
、HTTP2
以及面向未来的HTTP3
。
13. HTTP1.0
默认不使用持久连接
,每次请求都需要建立连接
,请求完毕就会断开连接
,但是通过设置Connection: keep-alive(默认为close)
,可以实现长连接;仅支持GET、POST、HEAD
请求方法;302状态码
并未被浏览器按照规范实现;- 使用
Expires
作为判断强缓存是否有效
的标准,使用Last-Modified和Last-Modified-Since
作为协商缓存是否有效
的标准; - 不支持
断点续传
; - 产生
队头阻塞问题
,因为要等待前一次的响应结果返回
,才能进行下一次响应
,如果前一次请求的响应很慢,那么就会产生阻塞;
14. HTTP1.1
默认使用持久连接
,即默认使用Connection: keep-alive
,建立连接之后发送请求,下次发送请求无需重新建立连接;- 新增了
PUT、DELETE、OPTIONS、CONNECT、TRACE
五种请求方法; - 新增了
303
、307
、308
状态码,将301
和302
状态码进行区分; - 使用
cache-control
作为判断强缓存是否有效
的标准,使用ETag和If-None-Match
作为协商缓存是否有效
的标准; - 支持
断点续传
,新增了206
状态码; - 引入
管道机制
,即在同一个TCP连接中
,HTTP请求
可以并行
,无需等待上一次的请求结果,就可以发送下一个请求,但是服务器必须按照客户端请求的先后顺序进行响应
,以便客户端能够正确的拿到响应结果
; - 并未真正解决
队头阻塞问题
,管道机制
解决了一部分的队头阻塞问题
,因为它允许多个请求并行发出
,但是它又要求响应结果按顺序返回
,如果说某一个请求响应需要很长时间,后续的请求响应必须要等到前一个请求的响应完毕,还是会造成阻塞
; 头部开销较大
,header中引入了很多的内容,导致每次发送请求都需要携带巨大的头部,开销较大;
15. HTTP2
- 默认
不再使用ASCII编码
传输,而是采用二进制数据
,客户端发起请求时,将请求内容封装成带有不同编号的二进制帧(Frame)
,然后发送给服务端,服务端进行拼接,得到完整的请求信息
,然后将响应结果也拆分成二进制帧
,客户端再进行拼装,拿到响应结果
,在HTTP1.1
中,头部是文本,数据部分可以是文本也可以是二进制,但是在HTTP2
中,都变成了二进制帧; 多路复用
:有了二进制帧
之后,只需要建立一个连接
即可完成通信需求,这种方式被称为多路复用
,每一条路称为stream(流)
,并且客户端和服务端可以同时发送或响应多个请求,无需按照顺序
,避免了队头阻塞
问题;头部信息压缩
,使用专门的头部压缩算法
,减少数据传输量,主要方式是通过客户端和服务端
同时维护一张头部信息表
,所有的头部信息都会在表里记录,并且对应一个索引
,下次发起请求时只需要携带索引
即可,比如第一次发送请求A
,依然会把请求头带过去,但是客户端和服务端会记录下来该请求的请求头,并维护在一张表里,下次再次发送请求A
的时候,就去表里找有没有请求A的请求头,如果有,只带一个索引即可;服务器主动推送
:允许服务端主动
向客户端推送数据,是Chrome106
版本禁用了,改为103状态码
;数据流
:HTTP2中
,因为数据传输不是有序的
,所以同一个TCP连接中
,相连的两个数据包不是同一个请求的,为了区分这种情况,每个请求或响应的数据包称之为一个数据流(stream)
,每一个数据流都有一个唯一的编号
,以便客户端或者服务端能够根据编号将它们分类
、组装
成一个完整的请求
或响应
;
16. HTTP3
- Goole发明了一个
基于UDP协议
的QUIC
协议,并在HTTP3上使用QUIC
。 QUIC协议
基于UDP
,无需进行建立连接,省去了三次握手的过程,速度更快;- 同样也提供了
拥塞控制
机制,包括慢启动
、拥塞避免
等; - 也实现了
多路复用
的功能,每个请求会在QUIC
中为一个stream
,并且相互隔离
,就算发生丢包也只影响当前stream
; - 也实现了
类似TCP的可靠传输
,比如发送第n个数据,TCP中只有收到了接收端的ACK报文,才会发送n+1,而QUIC中,不管接收端有没有接收,都会发送n+1,只不过n+1中的数据,标识还是为n,我们可以把每次发送的数据当作一个流stream
,每个stream
可以传输多个stream offset
,而stream offset指向的就是n
,接收端即使拿到了n+1的数据,进行拼装的时候还是会根据n来拼装; - 集成了
TLS
加密功能,目前QUIC
使用的是TLS1.3
,相较于早期版本,TLS1.3
有更多的优点,其中最重要的一点是减少了握手所花费的RTT
个数。
17. 为什么HTTP3会出现
HTTP3
最大的改变就是它采用了基于UDP协议
的传输协议,之所以会诞生出HTTP3,是因为之前的HTTP协议都是基于TCP的
,而TCP协议
天生在性能上就有一些缺陷。
TCP协议
是需要连接的,所以就必须要进行三次握手
,而UDP协议
是无连接的,节省了三次握手;TCP协议
就是会有可能产生队头阻塞问题
,无法改变;
队头阻塞
TCP协议
是可靠的
,所以它必须等到前一个数据传输完成
,并且接收到接收端发回的响应
,才会继续发送下一个数据,如果前一个数据丢包了,那就要等待重传
,否则后面的数据都需要排队,也就是说,把TCP连接看成一个队列,只要队头的不动,后面的都别想动。
这种机制保证了TCP协议的安全可靠性
,但是也会影响性能问题。
队头阻塞的解决方案
- HTTP1.1中使用
管道机制
,允许多个请求并行
,但是响应数据必须按照顺序
,所以说在数据响应时,还是会造成队头阻塞
; - HTTP2中,直接
放弃管道机制
,把数据改为了二进制帧进行传输
,利用编号
来将这些帧
进行分组拼装,不需要按顺序发送或返回,一定程度上解决了队头阻塞
,但是由于底层协议还是TCP
,如果数据发生丢包
,当前连接内的所有内容都要等待重传
,还是会造成阻塞
; - HTTP3为了彻底解决
队头阻塞
问题,直接将底层协议改为基于UDP协议实现
;
18. HTTP1.1、HTTP2、HTTP3总结
下一个版本一定是对上一个版本缺点的修复
,比如HTTP1.1中安全性不高
、性能不足
,在HTTP2中对其进行了头部压缩
、多路复用
、采用TLS加密传输
等优化,但是还存在队头阻塞的问题
,HTTP3又直接修改底层协议
,彻底解决队头阻塞问题
,即拥有TCP协议的安全可靠性,又具有UDP协议的性能。
19. HTTPS协议
HTTPS并不是
一个新的协议
,它是在HTTP
和TCP
的传输中建立了一个安全层
,它其实就是由HTTP协议+SSL/TLS协议
组合而成,本质上还是HTTP协议
,只是由SSL/TLS
进行了安全性的提升。
优点
- 相比于
HTTP协议
来说,它更加安全; HTTPS
对搜索引擎
更友好,利于SEO
,谷歌
、百度
优先索引HTTPS
网页;- 使用
HTTPS
协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
缺点
HTTPS证书
需要及时维护,并且还要花钱;HTTPS
加密解密需要消耗更多服务器资源;HTTPS
在握手阶段比较耗时;
和HTTP的区别
- HTTP是
明文传输
,HTTPS可以进行加密传输
,更加安全; - HTTPS标准端口
443
,HTTP标准端口80
; - HTTPS需要用到
SSL证书
,而HTTP不用;
20. SSL/TLS协议是什么
SSL(Secure Sockets Layer 安全套接层)
,传输层安全(Transport Layer Security,TLS)
是为网络通信提供安全及数据完整性的一种安全协议,TLS与SSL在传输层对网络连接进行加密。
21. HTTPS的握手
握手流程
- 客户端发起
HTTPS
请求,发送客户端生成的随机数
和支持的加密算法列表
; - 服务端返回
证书信息
、服务端生成的随机数
、选择使用的加密方法
给客户端; - 客户端对
证书进行合法性验证
,验证通过后再生成一个随机数
; - 客户端通过
证书中的公钥
对随机数进行加密
传输到服务端,服务端接收后通过私钥
解密得到该随机数
; - 三次握手此时
已经完成
,之后客户端和服务端都会根据这三个随机数
,生成一个随机对称密钥
,之后的数据都通过随机对称密钥
进行加密传输
。
如何验证证书的合法性
- 首先浏览器读取证书中的证书所有者、有效期等信息进行一一校验;
- 浏览器接着判断证书中的
颁发者CA
是否受信任,用以校验证书是否为合法机构颁发; - 如果证书不可信,浏览器就会提示证书不可信;
- 如果证书可信,那么浏览器就会用
CA机构
的公钥对证书里面的签名进行解密,得到hash
值和加密算法; - 再用证书里提到的加密算法,将证书的明文内容加密成另一个
hash
值,对比两个hash
值是否相同,相同则证明服务器发来的证书合法,没有被篡改; - 再比对一下证书中的域名和当前请求的域名是否一致,以确保证书不会被掉包;
- 此时浏览器就可以读取证书中的公钥,用于后续加密了。
为什么需要三个随机数
通过使用多个随机数
,可以增加密钥的复杂性
和安全性
,提高加密算法的强度,更好的保护数据。
22. 在浏览器中输入内容到按下回车,发生了什么?
输入
:浏览器会查看输入的是一个完整的URL
还是一个关键字
,如果是一个关键字,就会将其拼装成一个完整的URL
进行访问;检查缓存
:检查当前浏览器是否有该URL的缓存
,如果命中了强缓存
,就直接使用缓存;DNS解析
:如果没有命中强缓存,则需要发起请求,这时会根据域名
进行DNS解析
,通过递归查询
和迭代查询
,得到最终的IP地址
;建立TCP连接
:查找到IP之后进行TCP连接,进行三次握手;发送请求
:发送HTTP
请求,请求时会带上cookie
中保存的缓存标识
;服务器处理请求
:服务器网关请求之后,会在服务器内部对请求进行处理,具体如何处理,和服务器有关;服务器响应请求
:服务器处理完请求之后,如果命中了协商缓存
,就返回304状态码
,如果请求失败
,就返回对应的状态码,如果请求成功
,就返回200状态码
;浏览器接收响应
:浏览器收到服务器的响应,根据服务器是否开启了持久连接
,来决定是断开连接
还是继续保持TCP连接
,并且还会缓存响应头中缓存相关的标识
;开始页面渲染
:浏览器进行生成DOM树
、生成CSSOM树
、解析js脚本
、合并Render树
、计算样式
、生成布局树(Layout)
、分层
、下达绘制指令
、分块
、光栅化
、画
等操作;
23. 什么是DNS
域名系统
(英文:Domain Name System:DNS)是互联网
的一项服务。它作为将域名
和IP地址
相互映射
的一个分布式数据库
,能够使人更方便地访问互联网。DNS使用UDP端口53
。当前,对于每一级域名长度的限制是63个字符,域名总长度则不能超过253个字符。
也就是说,DNS
主要用途其实就是将域名解析成对应IP
的。
24. DNS查询方式
(1)递归查询
递归查询
指的是查询请求发出后,域名服务器代为
向下一级域名服务器发出请求,最后向用户返回查询的最终结果
。使用递归查询,用户只需要发出一次查询请求
。
(2)迭代查询
迭代查询
指的是查询请求发出后,域名服务器返回单次查询的结果
,下一级的查询由用户自己请求
,使用迭代查询,用户需要发出多次的查询请求
。
(3 DNS查询流程
比如我们想访问网页A
,它的网址为www.a.com
:
- 浏览器会查看
浏览器缓存中
有没有该域名的IP缓存
; - 如果没有,就会去
本机的hosts
文件查看有没有该域名的IP缓存
; - 如果还没有,浏览器就会请求
本地域名服务器
; - 本地域名服务器会
先查询自己的DNS缓存
; - 如果还没有,本地域名服务器则会向
根域名服务器
发起请求,根服务器会返回顶级域名服务器的地址
; - 然后本地域名服务器会向
顶级域名服务器
发送二级域名
,进行请求,获取权威域名服务器地址
; - 然后本地域名服务器向
权威域名服务器地址
发送请求,拿到IP地址; - 本机和浏览器会将该IP地址进行缓存;
比如www.a.com
,其中完整的写法
为www.a.com.
,最后的.
就是根域名
,访问时可以被忽略,而.com
就是顶级域名
,a.com
就是权威域名
。
在本地域名服务器之前
,进行的都是递归查询
,因为我们就发起了一次
域名的查询,递归查询了浏览器缓存
、hosts文件
、本地域名服务器
。
但是在本地域名服务器向根域名服务器发出请求之后
,就全部都是迭代查询了
,因为根域名服务器
返回了一个顶级域名服务器地址
,还是需要本地域名服务器再次请求
。
25. DNS为什么选择UDP协议作为传输层协议
在解析域名获得IP地址的过程中
,往往会多次向不同的域名服务器
发出请求,而TCP
协议存在三次握手,会造成DNS解析
变得很慢,使用UDP协议
,不需要进行三次握手,提升了查询的效率。
26. DNS实现负载均衡
DNS负载均衡技术的实现原理是
在DNS服务器中为同一个主机名配置多个IP地址
,在应答DNS查询时,DNS服务器对每个查询将以DNS文件中主机记录的IP地址按顺序
返回不同的解析结果,将客户端的访问引导到不同的机器上去
,使得不同的客户端访问不同的服务器,从而达到负载均衡的目的。
27. WebSocket
WebSocket是一种在
单个TCP
连接上进行全双工通信
的协议;WebSocket API也被W3C定为标准;
WebSocket使得客户端和服务器之间的数据交换
变得更加简单
,允许服务端主动向客户端推送数据
。在WebSocket API中,浏览器和服务器只需要完成一次握手
,两者之间就直接可以创建持久性的连接
,并进行双向数据传输
。
和HTTP的区别
相同点:
都是基于TCP协议
的可靠的应用层协议
。
不同点
WebSocket
是全双工通信协议
,通信双方可以在同一时间同时发送和接收消息
,而HTTP是单向的
;WebSocket
需要依赖HTTP协议
和服务器完成一次握手,然后就可以创建持久性的连接
,而HTTP
每次都需要重新建立连接
(当然,也可以完成持久连接);WebSocket
数据格式比较轻量,它的数据包头部较小,而HTTP
协议每次通信都需要携带完整的头部;WebSocket
没有跨域问题;WebSocket
可以由服务端主动推送消息
;
WebSocket握手与HTTP握手的区别
WebSocket
的握手报文相比HTTP
的握手报文,多了两个属性:
Upgrade:webSocket
(代表要在HTTP协议的基础上升级为WebSocket);Connection:Upgrade
(代表要对协议进行升级);
协议升级成功之后,服务端就会返回101
状态码,客户端收到101
状态码后就成功。
WebSocket 心跳
可能会有某些未知情况导致 socket
断开,而客户端和服务端却不知道
,需要客户端定时发送一个“心跳(ping)
让服务端知道自己在线;
服务端也需要回答一个“心跳”(pong)
告诉客户端自己可用,否则视为断开。
WebSocket状态
Constant | Value |
---|---|
WebSocket.CONNECTING(正在连接) | 0 |
WebSocket.OPEN(连接成功) | 1 |
WebSocket.CLOSING(正在关闭) | 2 |
WebSocket.CLOSED(已经关闭或者连接失败) | 3 |
WebSocket和Socket的区别是什么
Socket是TCP/IP网络的API
,是为了方便使用TCP或UDP
而抽象出来的一层,是位于应用层和传输控制层
之间的一组接口;
WebSocket
则是一个典型的应用层协议;
28. 即时通讯方案
短轮询
:客户端定时
向服务端发送请求,获取更新;长轮询
:是对短轮询的改进,请求到服务端后会被挂起
,直到有数据更新
,才会进行响应,然后由客户端再次发起请求;SSE
:基于HTTP协议中的持久连接
,作为HTML5的新功能,不用客户端发起请求,数据发生改变时,允许服务端主动推送数据
到客户端;WebSocket
:通过WebSocket
可以允许服务端主动推送数据到客户端;Socket.io
:其实Socket.IO
只是为了解决websocket的兼容性
的一个解决方案,因为websocket
出现的较新,所以一些老的浏览器兼容性不好,而Socket.IO
就是将websocket
、长轮询
两种通信方式
封装成了统一的通信接口进行降级兼容;
29. 计算机网络模型
TCP/IP五层模型、OSI七层模型
OSI
: 即Open System nterconnection,开放系统互连。它分为: 应用层
、表示层
、会话层
、传输层
、网络层
、数据链路层
、物理层
。
应用层
、表示层
、会话层
三个层次提供的服务相差不是很大
,所以在TCP/IP协议中,它们被合并为应用层
一个层次。
所以TCP/IP五层模型
分别为:应用层
、传输层
、网络层
、数据链路层
、物理层
;
- 我们常见的
HTTP
、WebSocket
、DNS
、HTTPS
等协议就是应用层协议
; - 而
TCP
、UDP
、TLS
协议则是传输层协议
; IP
则属于网络层协议
;
各层作用
应用层
:直接为应用进程提供服务,应用层协议定义的是应用进程间通讯和交互的规则,不同的应用有着不同的应用层协议;表示层
:数据格式化、加密、解密;会话层
:建立、维护、管理会话连接;传输层
:提供端对端的连接;网络层
:IP寻址和路由选择;数据链路层
:在网络层和物理层之间,负责向网络层提供服务;物理层
:通过光缆、无线电波等方式连接组网,传输比特流;