文章目录
- 计算机网络基础
- HTTP
- 从输入 URL 到页面展示到底发生了什么?(非常重要)
- HTTP请求的过程与原理
- 说说HTTP常用的状态码及其含义?
- 说说HTTP的状态码,301和302的区别?
- HTTP Header 中常见的字段有哪些?
- HTTP 常用的请求方式,区别和用途?
- POST和GET有哪些区别?
- 请简单说一下你了解的端口及对应的服务?
- HTTP/1.0、HTTP/1.1、HTTP/2.0、HTTP3.0的区别
- HTTPS流程是怎样的?
- HTTP 与 HTTPS 的区别
- 说说什么是数字签名?什么是数字证书?
- 对称加密与非对称加密有什么区别?
- HTTP 如何实现长连接?在什么时候会超时?
- HTTP 是不保存状态(无状态)的协议, 如何理解?如何保存用户状态?
- Cookie 和 Session 有什么区别, Cookie 和 Session 是如何配合的呢?
- token和Session的区别
- JWT
- URI和URL的区别
- forward和redirect的区别?
- DNS
- TCP 与 UDP
- TCP 与 UDP 的区别(重要)
- 什么时候选择 TCP,什么时候选 UDP?
- HTTP 基于 TCP 还是 UDP?
- 使用 TCP 的协议有哪些?使用 UDP 的协议有哪些?
- 请详细介绍一下TCP 的三次握手机制
- TCP握手为什么是三次,为什么不能是两次?不能是四次?
- 说说TCP四次挥手过程
- TCP挥手为什么需要四次呢?
- 为什么不能把服务端发送的 ACK 和 FIN 合并起来,变成三次挥手?
- TCP四次挥手过程中,为什么需要等待2MSL,才进入CLOSED关闭状态?
- 谈谈TCP的粘包和拆包?
- 说说TCP是如何确保可靠性的呢?
- 说说TCP报文首部有哪些字段,其作用又分别是什么?
- 聊聊TCP的流量控制和滑动窗口?
- TCP 的拥塞控制是怎么实现的?
- 说说TCP的重传机制
- IP
- ARP协议
- PING
- WebSocket
- 网络攻击相关
- 其他
计算机网络基础
计算机网络体系结构(网络分层模型)
OSI 七层模型是什么?每一层的作用是什么?
OSI 七层模型 是国际标准化组织提出的一个网络分层模型。每层的作用如下:
- 应用层
为计算机用户提供服务 - 表示层
数据处理(编解码、加密解密、压缩解压缩) - 会话层
管理(建立、维护、重连)应用程序之间的会话 - 传输层
为两台主机进程之间的通信提供通用的数据传输服务 - 网络层
路由和寻址 - 数据链路层
帧编码和误差纠正控制 - 物理层
透明地传送比特流
TCP/IP 四层模型是什么?每一层的作用是什么?
TCP/IP 四层模型 是目前被广泛采用的一种模型,我们可以将 TCP / IP 模型看作是 OSI 七层模型的精简版本,由以下 4 层组成:
- 应用层
对应于OSI参考模型的(应用层、表示层、会话层)。 - 传输层
对应OSI的传输层,为应用层实体提供端到端的通信功能,保证了数据包的顺序传送及数据的完整性。 - 网络层
对应于OSI参考模型的网络层,主要解决主机到主机的通信问题 - 网络接口层
与OSI参考模型的数据链路层、物理层对应。
五层体系结构以及对应的协议
- 应用层:对应于OSI参考模型的(应用层、表示层、会话层)。
- 传输层:对应OSI参考模型的的传输层
- 网络层:对应OSI参考模型的的网络层
- 数据链路层:对应OSI参考模型的的数据链路层
- 物理层:对应OSI参考模型的的物理层。
为什么网络要分层,分层的好处?
我觉得主要有 3 方面的原因:
- 各层之间相互独立:各层之间相互独立,各层之间不需要关心其他层是如何实现的,只需要知道自己如何调用下层提供好的功能就可以了(可以简单理解为接口调用)。
- 提高了灵活性和可替换性:每一层都可以使用最适合的技术来实现,并且,每一层都可以根据需要进行修改或替换,而不会影响到整个网络的结构。(高内聚、低耦合的原则)
- 大问题化小:分层可以将复杂的网络问题分解为许多比较小的、界线比较清晰简单的小问题来处理和解决。
常见网络协议有哪些,每一层常见协议有哪些?
应用层有哪些常见的协议?
- HTTP(Hypertext Transfer Protocol,超文本传输协议):基于 TCP 协议,是一种用于传输超文本和多媒体内容的协议,主要是为 Web 浏览器与 Web 服务器之间的通信而设计的。当我们使用浏览器浏览网页的时候,我们网页就是通过 HTTP 请求进行加载的。
- SMTP(Simple Mail Transfer Protocol,简单邮件发送协议):基于 TCP 协议,是一种用于发送电子邮件的协议。注意⚠️:SMTP 协议只负责邮件的发送,而不是接收。要从邮件服务器接收邮件,需要使用 POP3 或 IMAP 协议。
- POP3/IMAP(邮件接收协议):基于 TCP 协议,两者都是负责邮件接收的协议。IMAP 协议是比 POP3 更新的协议,它在功能和性能上都更加强大。IMAP 支持邮件搜索、标记、分类、归档等高级功能,而且可以在多个设备之间同步邮件状态。几乎所有现代电子邮件客户端和服务器都支持 IMAP。
- FTP(File Transfer Protocol,文件传输协议) : 基于 TCP 协议,是一种用于在计算机之间传输文件的协议,可以屏蔽操作系统和文件存储方式。注意 ⚠️:FTP 是一种不安全的协议,因为它在传输过程中不会对数据进行加密。建议在传输敏感数据时使用更安全的协议,如 SFTP。
- SSH(Secure Shell Protocol,安全的网络传输协议):基于 TCP 协议,通过加密和认证机制实现安全的访问和文件传输等业务。
- DNS(Domain Name System,域名管理系统): 基于 UDP 协议,用于解决域名和 IP 地址的映射问题。
传输层有哪些常见的协议?
- TCP(Transmission Control Protocol,传输控制协议 ):提供 面向连接 的,可靠 的数据传输服务。
- UDP(User Datagram Protocol,用户数据协议):提供 无连接 的,尽最大努力 的数据传输服务(不保证数据传输的可靠性),简单高效。
网络层有哪些常见的协议?
- IP(Internet Protocol,网际协议):主要作用是定义数据包的格式、对数据包进行路由和寻址,以便它们可以跨网络传播并到达正确的目的地。
- ARP(Address Resolution Protocol,地址解析协议):ARP 协议解决的是网络层地址和链路层地址之间的转换问题。ARP 协议解决了 IP 地址转 MAC 地址的一些问题。
- ICMP(Internet Control Message Protocol,互联网控制报文协议):一种用于传输网络状态和错误消息的协议,常用于网络诊断和故障排除。例如,Ping 工具就使用了 ICMP 协议来测试网络连通性。
- OSPF(Open Shortest Path First,开放式最短路径优先) ):一种内部网关协议(Interior Gateway Protocol,IGP),也是广泛使用的一种动态路由协议,基于链路状态算法,考虑了链路的带宽、延迟等因素来选择最佳路径。
- RIP(Routing Information Protocol,路由信息协议):一种内部网关协议(Interior Gateway Protocol,IGP),也是一种动态路由协议,基于距离向量算法,使用固定的跳数作为度量标准,选择跳数最少的路径作为最佳路径。
- BGP(Border Gateway Protocol,边界网关协议):一种用来在路由选择域之间交换网络层可达性信息(Network Layer Reachability Information,NLRI)的路由选择协议,具有高度的灵活性和可扩展性。
HTTP
从输入 URL 到页面展示到底发生了什么?(非常重要)
总体来说分为以下几个步骤:
- 在浏览器中输入指定网页的 URL。
- 浏览器通过 DNS 协议,获取域名对应的 IP 地址。
- 浏览器根据 IP 地址和端口号,向目标服务器发起一个 TCP 连接请求。
- 浏览器在 TCP 连接上,向服务器发送一个 HTTP 请求报文,请求获取网页的内容。
- 服务器收到 HTTP 请求报文后,处理请求,并返回 HTTP 响应报文给浏览器。
- 浏览器收到 HTTP 响应报文后,解析响应体中的 HTML 代码,渲染网页的结构和样式,同时根据 HTML 中的其他资源的 URL(如图片、CSS、JS 等),再次发起 HTTP 请求,获取这些资源的内容,直到网页完全加载显示。
- 浏览器在不需要和服务器通信时,可以主动关闭 TCP 连接,或者等待服务器的关闭请求。
HTTP请求的过程与原理
跟浏览器地址栏输入url到显示主页这道题有点类似。
- 客户端进行DNS域名解析,得到对应的IP地址
- 根据这个IP,找到对应的服务器建立连接(三次握手)
- 建立TCP连接后发起HTTP请求(一个完整的http请求报文)
- 服务器响应HTTP请求,客户端得到HTML代码
- 客户端解析HTML代码,用HTML代码中的资源(如js,css,图片等等)渲染页面。
- 服务器关闭TCP连接(四次挥手)
说说HTTP常用的状态码及其含义?
不管是不是面试需要,我们都要知道,日常开发中的这几个状态码的含义哈:
说说HTTP的状态码,301和302的区别?
302和301都有重定向的含义,但是它们也是有区别的。
- 301:(永久性转移)请求的网页已被永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。
- 302:(暂时性转移)服务器目前正从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。此代码与响应GET和HEAD请求的301代码类似,会自动将请求者转到不同的位置
HTTP Header 中常见的字段有哪些?
这里列举几个常见的:
- Accept
能够接受的回应内容类型(Content-Types) - Accept-Charset
能够接受的字符集 - Connection
该浏览器想要优先使用的连接类型 - Content-Type
请求体的多媒体类型(用于 POST 和 PUT 请求中) - Cookie
之前由服务器通过 Set-Cookie发送的一个超文本传输协议 Cookie - Host
Host 服务器的域名(用于虚拟主机),以及服务器所监听的传输控制协议端口号
HTTP 常用的请求方式,区别和用途?
POST和GET有哪些区别?
- 语义(主要区别):GET 通常用于获取或查询资源,而 POST 通常用于创建或修改资源。
- 幂等:GET 请求是幂等的,即多次重复执行不会改变资源的状态,而 POST 请求是不幂等的,即每次执行可能会产生不同的结果或影响资源的状态。
- 格式:GET 请求的参数通常放在 URL 中,形成查询字符串,而 POST 请求的参数通常放在请求体中,可以有多种编码格式。GET 请求的 URL 长度受到浏览器和服务器的限制,而 POST 请求的 body 大小则没有明确的限制。
- 缓存:由于 GET 请求是幂等的,它可以被浏览器或其他中间节点(如代理、网关)缓存起来,以提高性能和效率。而 POST 请求则不适合被缓存,因为它可能有副作用,每次执行可能需要实时的响应。
- 安全性:GET 请求和 POST 请求如果使用 HTTP 协议的话,那都不安全,因为 HTTP 协议本身是明文传输的,必须使用 HTTPS 协议来加密传输数据。另外,GET 请求相比 POST 请求更容易泄露敏感数据,因为 GET 请求的参数通常放在 URL 中。
请简单说一下你了解的端口及对应的服务?
HTTP/1.0、HTTP/1.1、HTTP/2.0、HTTP3.0的区别
HTTP/1.1 (相对于HTTP/1.0)
1、连接方式
HTTP 1.0默认使用短连接,即每个请求/响应后都会关闭连接,而HTTP 1.1默认使用长连接,在同一个连接上可以发送多个请求和响应。
2、状态响应码
HTTP/1.1 中新加入了大量的状态码
3、管道机制
HTTP 1.1支持请求管道化,即在一个持久连接上可以同时发送多个请求,而HTTP 1.0不支持请求管道化。
问题:采用管道机制虽然可以发送多个请求,但是服务器必须按照接收请求的顺序依次发送对这些管道化请求的响应,以保证客户端能够区分出每次请求的响应内容。这就导致了假如服务端在处理一个请求时耗时比较长,那么后续请求的处理都会被阻塞住,会导致客户端迟迟收不到数据,这称为「队头堵塞」–在HTTP2中解决。
4、缓存控制
HTTP/1.1 在 HTTP/1.0 基础之上,增加了一些请求响应头,以更好的实现对缓存的控制。
- 新增 Cache-Control 代替原先的 Expires;
- 新增 If-None-Match 和 Etag 代替原先的 If-Modified-Since和 Last-Modified 。
5、断点续传
HTTP1.0中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能, 而HTTP1.1则在请求头引入了range头域,它允许只请求资源的某个部分,即返回码是206(Partial Content)
6、Host 头
HTTP/1.1 引入了Host头,允许客户端指定请求的主机名,这使得在同一台服务器上托管多个域名成为可能。HTTP/1.0没有这个头字段。
HTTP/2.0 (相对于HTTP/1.1)
1、头部压缩
HTTP/1.1 支持Body压缩,Header不支持压缩。HTTP/2.0 支持对Header压缩,使用了专门为Header压缩而设计的 HPACK 算法,减少了网络开销。
客户端和服务器同时维护一张头信息表,高频出现的字段会存入这个表,生成一个索引号。发送报文时直接使用索引号替代字段。另外,索引表中不存在的字段使用压缩。同时,多个请求中,如果请求头相同,则后续请求只需要发送差异的部分,重复的部分无需再发送。
2、二进制帧
HTTP/2.0 使用二进制帧进行数据传输,而 HTTP/1.1 则使用文本格式的报文。二进制帧更加紧凑和高效,减少了传输的数据量和带宽消耗。
3、多路复用
HTTP/2.0 在同一连接上可以同时传输多个请求和响应(可以看作是 HTTP/1.1 中长链接的升级版本),互不干扰。HTTP/1.1 则使用串行方式,每个请求和响应都需要独立的连接,而浏览器为了控制资源会有 6-8 个 TCP 连接都限制。。这使得 HTTP/2.0 在处理多个请求时更加高效,减少了网络延迟和提高了性能。
- 在 HTTP/2 中定义了流(Stream)的概念,它是二进制帧的双向传输序列,一个数据流对应着一个完整的请求-响应过程,在同一个请求响应过程中,往返的帧会分配一个唯一的流编号(Stream ID)。
- 在流的支持下,HTTP/2 可以在一个 TCP 连接中传输多个请求或响应,而不用按照顺序一一对应(即实现多路复用),因为它们属于不同的流,所发送的帧头部都会携带 Stream ID,可以通过此 Stream ID 有效区分不同的请求-响应。
- 因而 HTTP/2 解决了 HTTP/1.1 的队头阻塞问题,多个请求 - 响应之间没有了顺序关系,不需要排队等待,降低了延迟,大幅度提高了连接的利用率。
4、服务器主动推送
HTTP/2.0 支持服务器推送,可以在客户端请求一个资源时,将其他相关资源一并推送给客户端,从而减少了客户端的请求次数和延迟。而 HTTP/1.1 需要客户端自己发送请求来获取相关资源。
比如当客户端向服务器请求一个 HTML 文件后,服务器除了将此 HTML 文件响应给客户端外,还可以提前主动将此 HTML 中所依赖的 JS 和 CSS 文件推送给客户端,这样客户端在解析 HTML 时,无需耗费额外的请求去得到相应的 JS 和 CSS 文件。
HTTP/3.0 (相对于HTTP/2.0)
1、传输协议
HTTP/2.0 是基于 TCP 协议实现的,HTTP/3.0 新增了 QUIC 协议来实现可靠的传输,提供与 TLS/SSL 相当的安全性,具有较低的连接和传输延迟。你可以将 QUIC 看作是 UDP 的升级版本,在其基础上新增了很多功能比如加密、重传等等。HTTP/3.0 之前名为 HTTP-over-QUIC,从这个名字中我们也可以发现,HTTP/3 最大的改造就是使用了 QUIC。
2、连接建立
HTTP/2.0 需要经过经典的 TCP 三次握手过程(由于安全的 HTTPS 连接建立还需要 TLS 握手,共需要大约 3 个 RTT)。由于 QUIC 协议的特性(TLS 1.3,TLS 1.3 除了支持 1 个 RTT 的握手,还支持 0 个 RTT 的握手)连接建立仅需 0-RTT 或者 1-RTT。这意味着 QUIC 在最佳情况下不需要任何的额外往返时间就可以建立新连接。
3、队头阻塞
HTTP/2.0 多请求复用一个 TCP 连接,一旦发生丢包,就会阻塞住所有的 HTTP 请求。由于 QUIC 协议的特性,HTTP/3.0 在一定程度上解决了队头阻塞(Head-of-Line blocking, 简写:HOL blocking)问题,一个连接建立多个不同的数据流,这些数据流之间独立互不影响,某个数据流发生丢包了,其数据流不受影响(本质上是多路复用+轮询)。
- HTTP/2 通过多路复用解决了 HTTP1.1 的队头阻塞问题,但其只是解决了 HTTP 这一层面的队头阻塞问题,底层仍然采用的 TCP 连接,HTTP/2 并没有解决 TCP 的队头阻塞问题。
- TCP 是可靠的、面向字节流的协议。HTTP/2 的多个请求虽然可以跑在同一个 TCP 连接中,但如果出现丢包现象,TCP 就需要进行重传,这可能就会导致整个 TCP 连接上的所有流阻塞,直到丢的包重传成功,这就是 TCP 的『队头阻塞』问题。
- 为了解决此问题,HTTP/3 底层不再使用 TCP,而是采用 UDP!而 UDP 是无连接的,多个流互相独立,之间不再有依赖,因而即使某个流发生了丢包,只会对该流产生影响,并不会使得其他流阻塞!
4、错误恢复
HTTP/3.0 具有更好的错误恢复机制,当出现丢包、延迟等网络问题时,可以更快地进行恢复和重传。而 HTTP/2.0 则需要依赖于 TCP 的错误恢复机制。
5、安全性
HTTP/2.0 和 HTTP/3.0 在加密通信实现上有所不同,HTTP/2.0 使用 TLS 协议进行加密,而 HTTP/3.0 基于 QUIC 协议,包含了内置的加密和身份验证机制,可以提供更强的安全性。
HTTP/1.0、HTTP/2.0 和 HTTP/3.0 的协议栈比较:
HTTPS流程是怎样的?
- 客户端发起Https请求,连接到服务器的443端口。
- 服务器必须要有一套数字证书(证书内容有公钥、证书颁发机构、失效日期等)。
- 服务器将自己的数字证书发送给客户端(公钥在证书里面,私钥由服务器持有)。
- 客户端收到数字证书之后,会验证证书的合法性。如果证书验证通过,就会生成一个随机的对称密钥,用证书的公钥加密。
- 客户端将公钥加密后的密钥发送到服务器。
- 服务器接收到客户端发来的密文密钥之后,用自己之前保留的私钥对其进行非对称解密,解密之后就得到客户端的密钥,然后用客户端密钥对返回数据进行对称加密,酱紫传输的数据都是密文啦。
服务器将加密后的密文返回到客户端。 - 客户端收到后,用自己的密钥对其进行对称解密,得到服务器返回的数据。
HTTP 与 HTTPS 的区别
- 端口号:HTTP 默认是 80,HTTPS 默认是 443
- URL 前缀:HTTP 的 URL 前缀是 http://,HTTPS 的 URL 前缀是 https://。
- 安全性和资源消耗: HTTP是明文传输,HTTPS所有传输的内容都经过加密
HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS 高,但是 HTTPS 比 HTTP 耗费更多服务器资源。
说说什么是数字签名?什么是数字证书?
数字证书是指在互联网通讯中标志通讯各方身份信息的一个数字认证,人们可以在网上用它来识别对方的身份。它的出现,是为了避免身份被篡改冒充的。比如Https的数字证书,就是为了避免公钥被中间人冒充篡改。
数字证书构成
- 公钥和个人等信息,经过Hash摘要算法加密,形成消息摘要;将消息摘要拿到拥有公信力的认证中心(CA),用它的私钥对消息摘要加密,形成数字签名。
- 公钥和个人信息、数字签名共同构成数字证书。
对称加密与非对称加密有什么区别?
- 对称加密:指加密和解密使用同一密钥,优点是运算速度较快,缺点是如何安全将密钥传输给另一方。常见的对称加密算法有:DES、AES等。
- 非对称加密:指的是加密和解密使用不同的密钥(即公钥和私钥)。公钥与私钥是成对存在的,如果用公钥对数据进行加密,只有对应的私钥才能解密。常见的非对称加密算法有RSA。
HTTP 如何实现长连接?在什么时候会超时?
HTTP的长连接实质是指TCP的长连接。至于什么时候超时,我们记住这几个参数如tcp_keepalive_time、tcp_keepalive_probes就好啦。
如何设置长连接?
通过在头部(请求和响应头)设置Connection字段指定为keep-alive,HTTP/1.0协议支持,但是是默认关闭的,从HTTP/1.1以后,连接默认都是长连接。
在什么时候会超时呢?
- HTTP一般会有httpd守护进程,里面可以设置keep-alive timeout,当tcp连接闲置超过这个时间就会关闭,也可以在HTTP的header里面设置超时时间。
- TCP 的keep-alive包含三个参数,支持在系统内核的net.ipv4里面设置;当 TCP 连接之后,闲置了tcp_keepalive_time,则会发生侦测包,如果没有收到对方的ACK,那么会每隔 tcp_keepalive_intvl再发一次,直到发送了tcp_keepalive_probes,就会丢弃该连接。
HTTP 是不保存状态(无状态)的协议, 如何理解?如何保存用户状态?
HTTP 是一种不保存状态,即无状态(stateless)协议。也就是说 HTTP 协议自身不对请求和响应之间的通信状态进行保存。
如何理解无状态这个词呢?
当浏览器第一次发送请求给服务器时,服务器响应了;如果同个浏览器发起第二次请求给服务器时,它还是会响应,但是呢,服务器不知道你就是刚才的那个浏览器。简言之,服务器不会去记住你是谁,所以是无状态协议。
如何保存用户状态?
通过Session保存,在服务端保存 Session 的方法很多,最常用的就是内存和数据库(比如是使用内存数据库 redis 保存)。既然 Session 存放在服务器端,那么我们如何实现 Session 跟踪呢? 大部分情况下,我们都是通过在 Cookie 中附加一个 Session ID 来方式来跟踪。
如果需要禁止浏览器的Cookie 那么怎么进行 session 校验呢?
- 将sessionid作为 URL 路径的附加信息(params)。
- 将sessionid作为查询字符串附加在 URL 后面(query)
关闭浏览器后 session 会消失吗?
这个问题需要从以下 2 个方面考虑:
- 从服务器端考虑:我们知道session是存在于服务器端内存中的,和浏览器没有关系,所以浏览器关闭后,服务器端的session不会消失。(除非服务器重启或session达到了过期时间)。
- 从浏览器端考虑:我们知道浏览器是根据cookie中的jesessionid值来唯一找到服务器端的session的,此时若cookie没有持久化,浏览器关闭后cookie也跟着消失。所以当用户再次打开浏览器后,由于没有了cookie中的jesessionid,自然也无法唯一找到服务器端的session,对用户来说,确实是浏览器关闭后再次打开就无法找到上次的会话了,误以为是关闭浏览器后服务器端的session也跟着消失,其实还在。
Cookie 和 Session 有什么区别, Cookie 和 Session 是如何配合的呢?
我们先来看Session和Cookie的概念吧:
- Cookie是保存在客户端的一小块文本串的数据。客户端向服务器发起请求时,服务端会向客户端发送一个Cookie,客户端就把Cookie保存起来。在客户端下次向同一服务器再发起请求时,Cookie被携带发送到服务器。服务器就是根据这个Cookie来确认身份的。
- session是基于cookie实现的,session存储在服务器端,每个session都会有一个对应的sessionID。
Cookie 和 Session 的共同之处
- cookie 和 session 都是用来跟踪浏览器用户身份的会话方式。
- session 和 cookie 都由服务器生成。
Session 和Cookie的区别主要有这些:
此外,session是基于cookie工作的(其实大部分的保存用户状态的操作都需要使用到cookie)
那么 Cookie 和 Session 是如何配合的呢
- 用户第一次请求服务器时,服务器根据用户提交的信息,创建对应的Session,请求返回时将此Session的唯一标识信息SessionID返回给浏览器,浏览器接收到服务器返回的SessionID信息后,会将此信息存入Cookie中,同时Cookie记录此SessionID是属于哪个域名。
- 当用户第二次访问服务器时,请求会自动判断此域名下是否存在Cookie信息,如果存在,则自动将Cookie信息也发送给服务端,服务端会从Cookie中获取SessionID,再根据 SessionID查找对应的 Session信息,如果没有找到,说明用户没有登录或者登录失效,如果找到Session证明用户已经登录可执行后面操作。
token和Session的区别
token:token是访问资源接口(API)时所需要的资源凭证。
token 的身份验证流程:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 token 并把这个 token 发送给客户端
- 客户端收到 token 以后,会把它存储起来,比如放在 cookie 里或者 localStorage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 token
- 服务端收到请求,然后去验证客户端请求里面带着的 token ,如果验证成功,就向客户端返回请求的数据
token和Session的区别
- Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。
- Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态。
JWT
什么是JWT?
JWT是一种基于Token的身份验证方式,它定义了一种紧凑的、自包含的方式,用于在双方之间安全地传输信息作为JSON对象。这些信息可以被验证、信任,因为它们是数字签名的。
JWT的结构
JWT主要由三部分构成,它们之间用点(.)分隔开来:
-
Header(头部):它是一个JSON对象,描述了JWT的元数据,通常包括两部分
- 类型(typ):通常是JWT。
- 签名算法(alg):如HMAC SHA256或RSA
-
Payload(有效载荷):它也是一个JSON对象,包含实际要传输的数据。
-
Signature(签名):为了生成签名,你必须有编码后的header和payload,以及一个密钥。签名用于验证消息的发送者是谁,以及消息在传输过程中没有被更改。
JWT的使用
- 生成JWT:
将Header和Payload分别Base64编码,然后用Header中指定的算法和密钥对这两部分进行签名。 - 发送JWT:
JWT通常在HTTP请求的Authorization头部中以Bearer token的形式发送。 - 验证和解析JWT:
接收方将验证JWT的签名,并根据需要解析Payload中的数据。
JWT和Session区别?
1、工作原理与存储位置
Session:Session机制依赖于服务器端的存储。JWT依赖客户端
2、数据安全性
- Session:因为用户信息存储在服务器端,相对而言更安全,不易受到攻击。但需要确保服务器和存储session数据的地方(如Redis或数据库)的安全性。
- JWT的Payload部分是可被 base64 解码查看的,虽然不加密,但不包含敏感信息,且JWT包含签名以防止篡改。尽管JWT可以设置过期时间增加安全性,但如果密钥泄露,则可能造成安全风险。
3、可扩展性和负载均衡
- Session:在分布式系统中,为了共享session信息,需要额外的配置(如sticky sessions或session复制/集中存储),这增加了系统的复杂度。
- JWT:因为JWT是自包含的,服务器之间不需要共享session信息,这使得JWT天然支持分布式环境和负载均衡,扩展性更好。
4、资源消耗
- Session:服务器需要为每个活跃会话分配存储空间,随着用户量的增长,可能会导致服务器资源紧张。
- JWT:服务器端无状态,不需存储会话信息,减少了服务器的资源消耗。
5、灵活性与控制
- Session:服务器可以主动废弃session,更易于管理和控制用户会话。
- JWT:一旦签发,除非设置短有效期或有刷新机制,否则服务器无法主动撤销,灵活性较低。
如何对JWT已签发的token 进行废弃处理?
如果想要对已签发的token进行废弃处理,就需要将token存入如redis、磁盘等存储介质中,只有进行了数据存储,才能够针对数据进行操作。
- 登录成功后,给浏览器响应令牌的同时,把该令牌存储到Redis中
- LoginInterceptor拦截器中,需要验证浏览器携带的令牌,并同时需要获取到Redis中的存储的与之相同的令牌,如果获取到证明令牌有效,如果没有获取到则令牌无效
如何实现JWT的续签?
最简单的一种方式是每次请求刷新JWT,即每个HTTP请求都返回一个新的JWT。这个方法不仅暴力不优雅,而且每次请求都要做JWT的加密解密,会带来性能问题。另一种方法是在redis中单独为每个JWT设置过期时间,每次访问时刷新JWT的过期时间
URI和URL的区别
- URI,全称是Uniform Resource Identifier),中文翻译是统一资源标志符,主要作用是唯一标识一个资源。
- URL,全称是Uniform Resource Location),中文翻译是统一资源定位符,主要作用是提供资源的路径。
打个经典比喻吧,URI像是身份证,可以唯一标识一个人,而URL更像一个住址,可以通过URL找到这个人。
forward和redirect的区别?
forward是转发,redirect是重定向。
- 浏览器 URL 地址:Forward 是服务器内部的重定向,服务器内部请求某个 servlet,然后
获取 响应的内容,浏览器的 URL 地址是不会变化的;Redirect 是客户端请求服务器,然
后服务器给 客户端返回了一个 302 状态码和新的 location,客户端重新发起 HTTP 请求,
服务器给客户端 响应 location 对应的 URL 地址,浏览器的 URL 地址发生了变化。 - 数据的共享:Forward 是服务器内部的重定向, request 在整个重定向过程中是不变的,
request 中的信息在 servlet 间是共享的。Redirect 发起了两次 HTTP 请求分别使用不
同的 request。 - 请求的次数:Forward 只有一次请求;Redirect 有两次请求。
DNS
DNS 的作用是什么?
DNS(Domain Name System)域名管理系统,是当用户使用浏览器访问网址之后,使用的第一个重要协议。DNS 要解决的是域名和 IP 地址的映射问题。
DNS 是应用层协议,它可以在 UDP 或 TCP 协议之上运行,端口为 53 。
DNS 服务器有哪些?
DNS 服务器自底向上可以依次分为以下几个层级(所有 DNS 服务器都属于以下四个类别之一):
- 根 DNS 服务器。根 DNS 服务器提供 TLD 服务器的 IP 地址。目前世界上只有 13 组根服务器,我国境内目前仍没有根服务器。
- 顶级域 DNS 服务器(TLD 服务器)。顶级域是指域名的后缀,如com、org、net和edu等。国家也有自己的顶级域,如uk、fr和ca。TLD 服务器提供了权威 DNS 服务器的 IP 地址。
- 权威 DNS 服务器。在因特网上具有公共可访问主机的每个组织机构必须提供公共可访问的 DNS 记录,这些记录将这些主机的名字映射为 IP 地址。
- 本地 DNS 服务器。每个 ISP(互联网服务提供商)都有一个自己的本地 DNS 服务器。当主机发出 DNS 请求时,该请求被发往本地 DNS 服务器,它起着代理的作用,并将该请求转发到 DNS 层次结构中。严格说来,不属于 DNS 层级结构
DNS 解析的过程是什么样的?
假设你要查询www.baidu.com的IP地址:
- 首先会查找浏览器的缓存,看看是否能找到www.baidu.com对应的IP地址,找到就直接返回;否则进行下一步。
- 将请求发往给本地DNS服务器,如果查找到也直接返回,否则继续进行下一步;
- 本地DNS服务器向根域名服务器发送请求,根域名服务器返回负责.com的顶级域名服务器的IP地址的列表。
- 本地DNS服务器再向其中一个负责.com的顶级域名服务器发送一个请求,返回负责.baidu的权威域名服务器的IP地址列表。
- 本地DNS服务器再向其中一个权威域名服务器发送一个请求,返回www.baidu.com所对应的IP地址。
DNS 劫持了解吗?
DNS 劫持是一种网络攻击,它通过修改 DNS 服务器的解析结果,使用户访问的域名指向错误的 IP 地址,从而导致用户无法访问正常的网站,或者被引导到恶意的网站。DNS 劫持有时也被称为 DNS 重定向、DNS 欺骗或 DNS 污染。
TCP 与 UDP
TCP 与 UDP 的区别(重要)
- TCP 面向连接,UDP面向无连接
- UDP不提供可靠服务,TCP 提供可靠的传输服务,TCP 在传递数据之前,会有三次握手来建立连接,而且在数据传递时,有确认、窗口、重传、拥塞控制机制。通过 TCP 连接传输的数据,无差错、不丢失、不重复、并且按序到达。
- TCP 传输是有状态的,这个有状态说的是 TCP 会去记录自己发送消息的状态比如消息是否发送了、是否被接收了等等。为此 ,TCP 需要维持复杂的连接状态表。而 UDP 是无状态服务,简单来说就是不管发出去之后的事情了。
- 由于使用 TCP 进行传输的时候多了连接、确认、重传等机制,所以 TCP 的传输效率要比 UDP 低很多。
- TCP 是面向字节流的,UDP 是面向报文的。
- TCP 只支持点对点通信,UDP 支持一对一、一对多、多对一、多对多;
- TCP 首部开销(20 ~ 60 字节)比 UDP 首部开销(8 字节)要大。
什么时候选择 TCP,什么时候选 UDP?
- UDP 一般用于即时通信,比如:语音、 视频、直播等等。这些场景对传输数据的准确性要求不是特别高,比如你看视频即使少个一两帧,实际给人的感觉区别也不大。
- TCP 用于对传输准确性要求特别高的场景,比如文件传输、发送和接收邮件、远程登录等等。
HTTP 基于 TCP 还是 UDP?
HTTP/3.0 之前是基于 TCP 协议的,而 HTTP/3.0 将弃用 TCP,改用 基于 UDP 的 QUIC 协议 。
此变化解决了 HTTP/2 中存在的队头阻塞问题。队头阻塞是指在 HTTP/2.0 中,多个 HTTP 请求和响应共享一个 TCP 连接,如果其中一个请求或响应因为网络拥塞或丢包而被阻塞,那么后续的请求或响应也无法发送,导致整个连接的效率降低。这是由于 HTTP/2.0 在单个 TCP 连接上使用了多路复用,受到 TCP 拥塞控制的影响,少量的丢包就可能导致整个 TCP 连接上的所有流被阻塞。HTTP/3.0 在一定程度上解决了队头阻塞问题,一个连接建立多个不同的数据流,这些数据流之间独立互不影响,某个数据流发生丢包了,其数据流不受影响(本质上是多路复用+轮询)
除了解决队头阻塞问题,HTTP/3.0 还可以减少握手过程的延迟。在 HTTP/2.0 中,如果要建立一个安全的 HTTPS 连接,需要经过 TCP 三次握手和 TLS 握手:
- TCP 三次握手:客户端和服务器交换 SYN 和 ACK 包,建立一个 TCP 连接。这个过程需要 1.5 个 RTT(round-trip time),即一个数据包从发送到接收的时间。
- TLS 握手:客户端和服务器交换密钥和证书,建立一个 TLS 加密层。这个过程需要至少 1 个 RTT(TLS 1.3)或者 2 个 RTT(TLS 1.2)。
所以,HTTP/2.0 的连接建立就至少需要 2.5 个 RTT(TLS 1.3)或者 3.5 个 RTT(TLS 1.2)。而在 HTTP/3.0 中,使用的 QUIC 协议(TLS 1.3,TLS 1.3 除了支持 1 个 RTT 的握手,还支持 0 个 RTT 的握手)连接建立仅需 0-RTT 或者 1-RTT。这意味着 QUIC 在最佳情况下不需要任何的额外往返时间就可以建立新连接。
使用 TCP 的协议有哪些?使用 UDP 的协议有哪些?
基于TCP的应用层协议有:HTTP、FTP、SMTP、TELNET、SSH
- HTTP 协议(HTTP/3.0 之前):超文本传输协议(HTTP,HyperText Transfer Protocol)是一种用于传输超文本和多媒体内容的协议。
- HTTPS 协议:更安全的超文本传输协议(HTTPS,Hypertext Transfer Protocol Secure),身披 SSL 外衣的 HTTP 协议
- FTP: File Transfer Protocol (文件传输协议), 默认端口(20用于传输数据,21用于传输控制信息)
- SMTP: Simple Mail Transfer Protocol (简单邮件传输协议) ,默认端口25
- TELNET: Teletype over the Network (网络电传), 默认端口23
- SSH:Secure Shell(安全外壳协议),默认端口 22
基于UDP的应用层协议:DNS、TFTP、SNMP
- DNS : Domain Name Service (域名服务),默认端口 53
- HTTP 协议(HTTP/3.0 ): HTTP/3.0 弃用 TCP,改用基于 UDP 的 QUIC 协议 。
- DNS:域名系统(DNS,Domain Name System)将人类可读的域名 (例如,www.baidu.comopen in new window) 转换为机器可读的 IP 地址 (例如,220.181.38.148)。 我们可以将其理解为专为互联网设计的电话薄。实际上,DNS 同时支持 UDP 和 TCP 协议。
请详细介绍一下TCP 的三次握手机制
- 一次握手:客户端发送带有 SYN(SEQ=x) 标志的数据包 -> 服务端,然后客户端进入 SYN_SEND 状态,等待服务端的确认;
- 二次握手:服务端发送带有 SYN+ACK(SEQ=y,ACK=x+1) 标志的数据包 –> 客户端,然后服务端进入 SYN_RECV 状态;
- 三次握手:客户端发送带有 ACK(ACK=y+1) 标志的数据包 –> 服务端,然后客户端和服务端都进入ESTABLISHED 状态,完成 TCP 三次握手
TCP握手为什么是三次,为什么不能是两次?不能是四次?
三次握手最主要的目的就是双方确认自己与对方的发送与接收是正常的。
- 第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常
- 第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常
- 第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常
三次握手就能确认双方收发功能都正常,缺一不可。
说说TCP四次挥手过程
- 第一次挥手:客户端发送一个 FIN(SEQ=x) 标志的数据包->服务端,用来关闭客户端到服务端的数据传送。然后客户端进入 FIN-WAIT-1 状态。
- 第二次挥手:服务端收到这个 FIN(SEQ=X) 标志的数据包,它发送一个 ACK (ACK=x+1)标志的数据包->客户端 。然后服务端进入 CLOSE-WAIT 状态,客户端进入 FIN-WAIT-2 状态。
- 第三次挥手:服务端发送一个 FIN (SEQ=y)标志的数据包->客户端,请求关闭连接,然后服务端进入 LAST-ACK 状态。
- 第四次挥手:客户端发送 ACK (ACK=y+1)标志的数据包->服务端,然后客户端进入TIME-WAIT状态,服务端在收到 ACK (ACK=y+1)标志的数据包后进入 CLOSE 状态。此时如果客户端等待 2MSL 后依然没有收到回复,就证明服务端已正常关闭,随后客户端也可以关闭连接了。
只要四次挥手没有结束,客户端和服务端就可以继续传输数据!
TCP挥手为什么需要四次呢?
TCP 是全双工通信,可以双向传输数据。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后进入半关闭状态。当另一方也没有数据再发送的时候,则发出连接释放通知,对方确认后就完全关闭了 TCP 连接。
举个例子:A 和 B 打电话,通话即将结束后。
- 第一次挥手:A 说“我没啥要说的了”
- 第二次挥手:B 回答“我知道了”,但是 B 可能还会有要说的话,A 不能要求 B 跟着自己的节奏结束通话
- 第三次挥手:于是 B 可能又巴拉巴拉说了一通,最后 B 说“我说完了”
- 第四次挥手:A 回答“知道了”,这样通话才算结束。
为什么不能把服务端发送的 ACK 和 FIN 合并起来,变成三次挥手?
因为服务端收到客户端断开连接的请求时,可能还有一些数据没有发完,这时先回复 ACK,表示接收到了断开连接的请求。等到数据发完之后再发 FIN,断开服务端到客户端的数据传送。
TCP四次挥手过程中,为什么需要等待2MSL,才进入CLOSED关闭状态?
第四次挥手时,客户端发送给服务端的 ACK 有可能丢失,如果服务端因为某些原因而没有收到 ACK 的话,服务端就会重发 FIN,如果客户端在 2*MSL 的时间内收到了 FIN,就会重新发送 ACK 并再次等待 2MSL(超时 + 1MSL 传输),防止 Server 没有收到 ACK 而不断重发 FIN。
MSL(Maximum Segment Lifetime) : 一个片段在网络中最大的存活时间,2MSL 就是一个发送和一个回复所需的最大时间。如果直到 2MSL,Client 都没有再次收到 FIN,那么 Client 推断 ACK 已经被成功接收,则结束 TCP 连接。
谈谈TCP的粘包和拆包?
TCP是面向流,没有界限的一串数据,TCP也没有数据包长度字段。TCP底层并不了解上层业务数据的具体含义,它会根据TCP缓冲区的实际情况进行包的划分,所以在业务上认为,一个完整的包可能会被TCP拆分成多个包进行发送,也有可能把多个小的包封装成一个大的数据包发送,这就是所谓的TCP粘包和拆包问题。
为什么会产生粘包和拆包呢?
- 要发送的数据小于TCP发送缓冲区的大小,TCP将多次写入缓冲区的数据一次发送出去,将会发生粘包;
- 接收数据端的应用层没有及时读取接收缓冲区中的数据,将发生粘包;
- 要发送的数据大于TCP发送缓冲区剩余空间大小,将会发生拆包;
- 待发送数据大于MSS(最大报文长度),TCP在传输前将进行拆包。即TCP报文长度-TCP头部长度>MSS
解决方案:
- 发送端将每个数据包封装为固定长度
- 在数据尾部增加特殊字符进行分割
- 将数据分为两部分,一部分是头部,一部分是内容体;其中头部结构大小固定,且有一个字段声明内容体的大小。
实际应用:
说说TCP是如何确保可靠性的呢?
TCP是可靠的连接,为什么具有可靠性呢?记住这些点:连接和断开的可靠性(三次握手,四次挥手)、有状态(哪些数据发送了,哪些没发)、可控制(超时重传、流量控制、拥塞控制等)
- 首先,TCP的连接是基于三次握手,而断开则是基于四次挥手。确保连接和断开的可靠性。
- 其次,TCP的可靠性,还体现在有状态;TCP会记录哪些数据发送了,哪些数据被接收了,哪些没有被接受,并且保证数据包按序到达,保证数据传输不出差错。
- 再次,TCP的可靠性,还体现在可控制。它有数据包校验、ACK应答、超时重传(发送方)、失序数据重传(接收方)、丢弃重复数据、流量控制(滑动窗口)和拥塞控制等机制。
说说TCP报文首部有哪些字段,其作用又分别是什么?
- 16位端口号:源端口号,主机该报文段是来自哪里;目标端口号,要传给哪个上层协议或应用程序
- 32位序号:一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。
- 32位确认号:用作对另一方发送的tcp报文段的响应。其值是收到的TCP报文段的序号值加1。
- 4位头部长度:表示tcp头部有多少个32bit字(4字节)。因为4位最大能标识15,所以TCP头部最长是60字节。
- 6位标志位:URG(紧急指针是否有效),ACK(表示确认号是否有效),PSH(缓冲区尚未填满),RST(表示要求对方重新建立连接),SYN(建立连接消息标志接),FIN(表示告知对方本端要关闭连接了)
- 16位窗口大小:是TCP流量控制的一个手段。这里说的窗口,指的是接收通告窗口。它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度。
- 16位校验和:由发送端填充,接收端对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分。这也是TCP可靠传输的一个重要保障。
- 16位紧急指针:一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。
聊聊TCP的流量控制和滑动窗口?
TCP 提供一种机制可以让发送端根据接收端的实际接收能力控制发送的数据量,这就是流量控制。
为什么需要流量控制?
发送端不能疯狂地向接收端发送数据,因为接收端接收不过来的话,接收方只能把处理不过来的数据存在缓存区里。如果缓存区都满了,发送方还在疯狂发送数据的话,接收方只能把收到的数据包丢掉,这就浪费了网络资源啦。
怎么实现流量控制?
TCP 利用滑动窗口实现流量控制。流量控制是为了控制发送方发送速率,保证接收方来得及接收。 接收方发送的确认报文中的窗口字段可以用来控制发送方窗口大小,从而影响发送方的发送速率。
聊聊滑动窗口
TCP头部有个字段叫win,也即那个16位的窗口大小,它告诉对方本端的TCP接收缓冲区还能容纳多少字节的数据,这样对方就可以控制发送数据的速度,从而达到流量控制的目的。
通俗点讲,就是接受方每次收到数据包,在发送确认报文的时候,同时告诉发送方,自己的缓存区还有多少空余空间,缓冲区的空余空间,我们就称之为接受窗口大小。这就是win。
TCP 滑动窗口分为两种: 发送窗口和接收窗口。
发送端的滑动窗口包含四大部分,如下:
- 已发送且已收到ACK确认
- 已发送但未收到ACK确认
- 未发送但可以发送
- 未发送也不可以发送
- 虚线矩形框,就是发送窗口。
- SND.WND: 表示发送窗口的大小,上图虚线框的格子数是14个,即发送窗口大小是14。
- SND.NXT:下一个发送的位置,它指向未发送但可以发送的第一个字节的序列号。
- SND.UNA: 一个绝对指针,它指向的是已发送但未确认的第一个字节的序列号。
接收方的滑动窗口包含三大部分,如下:
- 已成功接收并确认
- 未收到数据但可以接收
- 未收到数据并不可以接收的数据
- 虚线矩形框,就是接收窗口。
- REV.WND: 表示接收窗口的大小,上图虚线框的格子就是9个。
- REV.NXT:下一个接收的位置,它指向未收到但可以接收的第一个字节的序列号。
接收窗口的大小是根据接收端处理数据的速度动态调整的。 如果接收端读取数据快,接收窗口可能会扩大。 否则,它可能会缩小。
TCP 的拥塞控制是怎么实现的?
拥塞控制是作用于网络的,防止过多的数据包注入到网络中,避免出现网络负载过大的情况。它的目标主要是最大化利用网络上瓶颈链路的带宽。它跟流量控制又有什么区别呢?流量控制是作用于接收者的,根据接收端的实际接收能力控制发送速度,防止分组丢失的。
为了进行拥塞控制,TCP 发送方要维持一个 拥塞窗口(cwnd) 的状态变量。拥塞控制窗口的大小取决于网络的拥塞程度,并且动态变化。发送方让自己的发送窗口取为拥塞窗口和接收方的接受窗口中较小的一个。
拥塞控制主要有这几种常用算法:
- 慢启动
- 拥塞避免
- 拥塞发生
- 快速恢复
慢启动算法
由小到大逐渐增加拥塞窗口的大小,如果没有出现丢包,每收到一个ACK,就将拥塞窗口cwnd大小就加1(单位是MSS)。每轮次发送窗口增加一倍,呈指数增长,如果出现丢包,拥塞窗口就减半,进入拥塞避免阶段。
为了防止cwnd增长过大引起网络拥塞,还需设置一个慢启动阀值ssthresh(slow start threshold)状态变量。当cwnd到达该阀值后,就好像水管被关小了水龙头一样,减少拥塞状态。即当cwnd >ssthresh时,进入了拥塞避免算法。
拥塞避免算法
拥塞避免算法的思路是让拥塞窗口 cwnd 缓慢增大,即每经过一个往返时间 RTT 就把发送方的 cwnd 加 1。
一般来说,慢启动阀值ssthresh是65535字节,cwnd到达慢启动阀值后
- 每收到一个ACK时,cwnd = cwnd + 1/cwnd
- 当每过一个RTT时,cwnd = cwnd + 1
显然这是一个线性上升的算法,避免过快导致网络拥塞问题。
拥塞发生算法
当网络拥塞发生丢包时,会有两种情况:
- RTO(重传超时时间)超时重传
- 快速重传
如果是发生了RTO超时重传,就会使用拥塞发生算法
-
慢启动阀值sshthresh = cwnd /2
-
cwnd 重置为 1
-
进入新的慢启动过程
这真的是辛辛苦苦几十年,一朝回到解放前。其实还有更好的处理方式,就是快速重传。发送方收到3个连续重复的ACK时,就会快速地重传,不必等待RTO超时再重传。
这样,慢启动阀值ssthresh 和 cwnd 变化如下: -
拥塞窗口大小 cwnd = cwnd/2
-
慢启动阀值 ssthresh = cwnd
-
进入快速恢复算法
快速恢复算法
快速重传和快速恢复算法一般同时使用。快速恢复算法认为,还有3个重复ACK收到,说明网络也没那么糟糕,所以没有必要像RTO超时那么强烈。
正如前面所说,进入快速恢复之前,cwnd 和 sshthresh已被更新:
- 拥塞窗口大小 cwnd = cwnd/2
- 慢启动阀值 ssthresh = cwnd
然后,真正的快速算法如下:
- cwnd = sshthresh + 3
- 重传重复的那几个ACK(即丢失的那几个数据包)
- 如果再收到重复的 ACK,那么 cwnd = cwnd +1
- 如果收到新数据的 ACK 后, cwnd = sshthresh。因为收到新数据的 ACK,表明恢复过程已经结束,可以再次进入了拥塞避免的算法了。
说说TCP的重传机制
重传包括超时重传、快速重传、带选择确认的重传(SACK)、重复SACK四种。
超时重传
超时重传,是TCP协议保证数据可靠性的另一个重要机制,其原理是在发送某一个数据以后就开启一个计时器,在一定时间内如果没有得到发送的数据报的ACK报文,那么就重新发送数据,直到发送成功为止。
RTT就是数据完全发送完,到收到确认信号的时间,即数据包的一次往返时间。超时重传时间,就是RTO(Retransmission Timeout)。
那么,RTO到底设置多大呢?
- 如果RTO设置很大,等了很久都没重发,这样肯定就不行。
- 如果RTO设置很小,那很可能数据都没有丢失,就开始重发了,这会导致网络阻塞,从而恶性循环,导致更多的超时出现。
超时重传不是十分完美的重传方案,它有这些缺点:
- 当一个报文丢失时,会等待一定的超时周期,才重传分组,增加了端到端的时延。
- 当一个报文丢失时,在其等待超时的过程中,可能会出现这种情况:其后的报文段已经被接收端接收但却迟迟得不到确认,发送端会认为也丢失了,从而引起不必要的重传,既浪费资源也浪费时间。
并且,对于TCP,如果发生一次超时重传,时间间隔下次就会加倍。
快速重传
快速重传在前面介绍过了,发送方收到三个重复ACK的确认,于是知道哪个报文段在传输过程中丢失了;发送方在定时器过期之前,重传该报文段。
快速重传也可能有问题:ACK只向告知发送方,最大的有序报文段。到底是哪个报文丢失了呢?并不确定!那到底该重传多少个包呢?
带选择确认的重传(SACK)
为了解决:应该重传多少个包的问题? TCP提供了带选择确认的重传。
SACK机制就是,在快速重传的基础上,接收方返回最近收到报文段的序列号范围,这样发送方就知道接收方哪些数据包是没收到的。这样就很清楚应该重传哪些数据包啦。
重复SACK(D-SACK)
D-SACK,英文是Duplicate SACK,是在SACK的基础上做了一些扩展,主要用来告诉发送方,有哪些数据包,自己重复接受了。DSACK的目的是帮助发送方判断,是否发生了包失序、ACK丢失、包重复或伪重传。让TCP可以更好的做网络流控。
IP
IPv4 和 IPv6 有什么区别?
- 地址长度与数量: IPV4的地址长度为32位,即4个字节,IPV6的地址长度达到了128位,即16个字节。
- 表示方法不同: IPV4地址以小数表示的二进制数来描述,而IPV6地址则采用十六进制的二进制数来表示。
- 头部长度:IPV4的包头长度为20个字节,而IPV6的包头长度为40个字节。
- 安全性:IPV4在安全性方面相对较弱,没有内置的身份验证和加密功能。而IPV6则在这方面进行了显著的改进,提供了身份验证和加密功能,从而增强了网络的安全性。
IP地址有哪些分类?
一般可以这么认为,IP地址=网络号+主机号。
网络号:它标志主机所连接的网络地址表示属于互联网的哪一个网络。
主机号:它标志主机地址表示其属于该网络中的哪一台主机。
IP地址分为A,B,C,D,E五大类:
- A类地址(1~126):以0开头,网络号占前8位,主机号占后面24位。
- B类地址(128~191):以10开头,网络号占前16位,主机号占后面16位。
- C类地址(192~223):以110开头,网络号占前24位,主机号占后面8位。
- D类地址(224~239):以1110开头,保留位多播地址。
- E类地址(240~255):以11110开头,保留位为将来使用
以上的是公共地址。
私有地址:
- 10.0.0.0-10.255.255.255
- 172.16.0.0 - 172.31.255.255
- 192.168.0.0-192.168.255.255
此外:
- 0.0.0.0 路由器转发使用
- 127.x.x.x 保留
- 255.255.255.255 局域网下的广播地址
ARP协议
说下ARP 协议的工作过程?
ARP 协议协议,Address Resolution Protocol,地址解析协议,它是用于实现IP地址到MAC地址的映射。
-
首先,每台主机都会在自己的ARP缓冲区中建立一个ARP列表,以表示IP地址和MAC地址的对应关系。
-
当源主机需要将一个数据包要发送到目的主机时,会首先检查自己的ARP列表,是否存在该IP地址对应的MAC地址;如果有,就直接将数据包发送到这个MAC地址;如果没有,就向本地网段发起一个ARP请求的广播包,查询此目的主机对应的MAC地址。此ARP请求的数据包里,包括源主机的IP地址、硬件地址、以及目的主机的IP地址。
-
网络中所有的主机收到这个ARP请求后,会检查数据包中的目的IP是否和自己的IP地址一致。如果不相同,就会忽略此数据包;如果相同,该主机首先将发送端的MAC地址和IP地址添加到自己的ARP列表中,如果ARP表中已经存在该IP的信息,则将其覆盖,然后给源主机发送一个 ARP响应数据包,告诉对方自己是它需要查找的MAC地址。
-
源主机收到这个ARP响应数据包后,将得到的目的主机的IP地址和MAC地址添加到自己的ARP列表中,并利用此信息开始数据的传输。如果源主机一直没有收到ARP响应数据包,表示ARP查询失败。
PING
PING 命令的作用是什么?
PING 命令是一种常用的网络诊断工具,经常用来测试网络中主机之间的连通性和网络延迟。
PING 命令的输出结果通常包括以下几部分信息:
- ICMP Echo Request(请求报文)信息:序列号、TTL(Time to Live)值。
- 目标主机的域名或 IP 地址:输出结果的第一行。
- 往返时间(RTT,Round-Trip Time):从发送 ICMP Echo Request(请求报文)到接收到 ICMP Echo Reply(响应报文)的总时间,用来衡量网络连接的延迟。
- 统计结果(Statistics):包括发送的 ICMP 请求数据包数量、接收到的 ICMP 响应数据包数量、丢包率、往返时间(RTT)的最小、平均、最大和标准偏差值。
PING 命令的工作原理是什么?
PING 基于网络层的 ICMP(Internet Control Message Protocol,互联网控制报文协议),其主要原理就是通过在网络上发送和接收 ICMP 报文实现的。
PING 命令的工作流程?
- ping通知系统,新建一个固定格式的ICMP请求数据包
- ICMP协议,将该数据包和目标机器B的IP地址打包,一起转交给IP协议层
- IP层协议将本机IP地址为源地址,机器B的IP地址为目标地址,加上一些其他的控制信息,构建一个IP数据包
- 先获取目标机器B的MAC地址。
- 数据链路层构建一个数据帧,目的地址是IP层传过来的MAC地址,源地址是本机的MAC地址
- 机器B收到后,对比目标地址,和自己本机的MAC地址是否一致,符合就处理返回,不符合就丢弃。
- 根据目的主机返回的ICMP回送回答报文中的时间戳,从而计算出往返时间
- 最终显示结果有这几项:发送到目的主机的IP地址、发送 & 收到 & 丢失的分组数、往返时间的最小、最大& 平均值
WebSocket
什么是 WebSocket?
WebSocket 是一种基于 TCP 连接的全双工通信协议,即客户端和服务器可以同时发送和接收数据。
WebSocket 协议本质上是应用层的协议,用于弥补 HTTP 协议在持久通信能力上的不足。客户端和服务器仅需一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
WebSocket 和 HTTP 有什么区别?
WebSocket 和 HTTP 两者都是基于 TCP 的应用层协议,都可以在网络中传输数据。
下面是二者的主要区别:
- WebSocket 是一种双向实时通信协议,而 HTTP 是一种单向通信协议。并且,HTTP 协议下的通信只能由客户端发起,服务器无法主动通知客户端。
- WebSocket 使用 ws:// 或 wss://(使用 SSL/TLS 加密后的协议,类似于 HTTP 和 HTTPS 的关系) 作为协议前缀,HTTP 使用 http:// 或 https:// 作为协议前缀。
- WebSocket 可以支持扩展,用户可以扩展协议,实现部分自定义的子协议,如支持压缩、加密等。
- WebSocket 通信数据格式比较轻量,用于协议控制的数据包头部相对较小,网络开销小,而 HTTP 通信每次都要携带完整的头部,网络开销较大(HTTP/2.0 使用二进制帧进行数据传输,还支持头部压缩,减少了网络开销)。
WebSocket 的工作过程是什么样的?
- 客户端向服务器发送一个 HTTP 请求,请求头中包含 Upgrade: websocket 和 Sec-WebSocket-Key 等字段,表示要求升级协议为 WebSocket;
- 服务器收到这个请求后,会进行升级协议的操作,如果支持 WebSocket,它将回复一个 HTTP 101 状态码,响应头中包含 ,Connection: Upgrade和 Sec-WebSocket-Accept: xxx 等字段、表示成功升级到 WebSocket 协议。
- 客户端和服务器之间建立了一个 WebSocket 连接,可以进行双向的数据传输。数据以帧(frames)的形式进行传送,WebSocket 的每条消息可能会被切分成多个数据帧(最小单位)。发送端会将消息切割成多个帧发送给接收端,接收端接收消息帧,并将关联的帧重新组装成完整的消息。
- 客户端或服务器可以主动发送一个关闭帧,表示要断开连接。另一方收到后,也会回复一个关闭帧,然后双方关闭 TCP 连接。
网络攻击相关
什么是CSRF 攻击,如何解决?
CSRF,跨站请求伪造(英文全称是Cross-site request forgery),其实就是通过伪装成受信任用户请求受信任的网站。
CSRF攻击原理及过程:
-
用户登录了A网站。
-
黑客诱导用户访问含有恶意代码的B网站。
-
B网站要求浏览器向A网站发送GET、POST等恶意请求。
-
用户没有退出A网站情况下,恶意请求自动携带用户的身份认证信息(Cookie、Session ID等)。
-
A网站确认了用户凭证,误以为是用户的请求以用户的名义执行了恶意操作。
所以要被CSRF攻击,必须同时满足两个条件:
- 登录受信任网站A,并在本地生成Cookie。
- 在不登出A的情况下,访问危险网站B。
怎么解决CSRF攻击呢?
- 验证 HTTP Referer 字段
- 添加校验token
什么是XSS攻击,如何避免?
XSS攻击是Web攻击中最常见的攻击方法之一,它是通过对网页注入可执行代码且成功地被浏览器 执行,达到攻击的目的。
如何解决XSS攻击问题?
- 一种方法是在表单提交或者url参数传递前,对需要的参数进行过滤
- 过滤用户输入的 检查用户输入的内容中是否有非法内容。如<>(尖括号)、”(引号)、 ‘(单引号)、%(百分比符号)、;(分号)、()(括号)、&(& 符号)、+(加号)等。、严格控制输出
- 对于链接跳转,如<a href=“xxx” 等,要校验内容,禁止以script开头的非法链接。
- 限制输入长度
聊聊SQL注入?
SQL注入是一种代码注入技术,一般被应用于攻击web应用程序。它通过在web应用接口传入一些特殊参数字符,来欺骗应用服务器,执行恶意的SQL命令,以达到非法获取系统信息的目的。它目前是黑客对数据库进行攻击的最常用手段之一。
如何预防SQL注入问题?
- 使用#{}而不是 ${}
因为#{}是一个参数占位符,对于字符串类型,会自动加上"",其他类型不加。由于Mybatis采用预编译,其后的参数不会再进行SQL编译,所以一定程度上防止SQL注入。
${}是一个简单的字符串替换,字符串是什么,就会解析成什么,存在SQL注入风险
- 不相信任何外部输入参数,过滤参数中含有的一些数据库关键词关键词
可以加个参数校验过滤的方法,过滤union,or等数据库关键词 - 适当的权限控制
说说SYN Flood攻击?
- 客户端发送一个 SYN包 给服务端后就退出,而服务端接收到 SYN包 后,会回复一个 SYN+ACK包 给客户端,然后等待客户端回复一个 ACK包。
- 但此时客户端并不会回复 ACK包,所以服务端只能一直等待直到超时。服务端超时后,会重发 SYN+ACK包 给客户端,默认会重试 5 次,而且每次等待的时间都会增加(可以参考 TCP 协议超时重传的实现)。
- 另外,当服务端接收到 SYN包 后,会建立一个半连接状态的 Socket。所以,当客户端一直发送 SYN包,但不回复 ACK包,那么将会耗尽服务端的资源,这就是 SYN Flood 攻击。
解决办法:
- 监视SYN包: 如果发现某个IP发送了大量的SYN报文,直接将这个IP列入黑名单即可
- 调整TCP/IP协议栈参数:可以减少SYN包的重试次数,限制同时处理的半连接数量,缩短SYN包超时时间等。
- 增加连接队列大小:服务器在处理连接请求时,会将请求放入一个队列中进行处理。增加连接队列大小可以增加服务器同时处理连接的能力,从而一定程度上减轻SYN攻击带来的负担。
- 使用SYN Cookie技术:SYN Cookie是一种用于防范SYN攻击的技术。当服务器收到SYN包时,不立即分配资源,而是根据源IP地址、端口和初始序号等信息生成一个加密的cookie并发送给客户端。当客户端发送ACK包时,服务器根据cookie解密还原出连接请求信息,并建立连接。这种方法可以有效防止服务器资源被大量半连接请求耗尽。
什么是DoS、DDoS、DRDoS攻击?
- DOS: (Denial of Service),翻译过来就是拒绝服务,一切能引起DOS行为的攻击都被称为DOS攻击。最常见的DoS攻击就有计算机网络宽带攻击、连通性攻击。
- DDoS: (Distributed Denial of Service),翻译过来是分布式拒绝服务。是指处于不同位置的多个攻击者同时向一个或几个目标发动攻击,或者一个攻击者控制了位于不同位置的多台机器并利用这些机器对受害者同时实施攻击。常见的DDos有SYN Flood、Ping of Death、ACK Flood、UDP Flood等。
- DRDoS: (Distributed Reflection Denial of Service),中文是分布式反射拒绝服务,该方式靠的是发送大量带有被害者IP地址的数据包给攻击主机,然后攻击主机对IP地址源做出大量回应,从而形成拒绝服务攻击。
其他
什么是CDN?CDN的工作原理是怎样的?
1.什么是CDN?
CDN的全称是Content Delivery Network,即内容分发网络。CDN是构建在网络之上的内容分发网络,依靠部署在各地的边缘服务器,通过中心平台的负载均衡、内容分发、调度等功能模块,使用户就近获取所需内容,降低网络拥塞,提高用户访问响应速度和命中率。CDN的关键技术主要有内容存储和分发技术。
2.基本原理
CDN的基本原理是在用户访问相对集中的地区和网络设置一些缓存服务器。当用户访问网站时,利用全局的负载均衡技术将用户的访问指向距离最近的缓存服务器,由缓存服务器代替源站响应用户的访问请求。这样一方面减轻了源站服务器的工作压力,另一方面使用户可就近取得所需内容,解决 Internet网络拥挤的状况,提高用户访问网站的响应速度。
如何实现跨域?
当域名,端口,协议三者存在任意一项不同时就需要解决跨域问题
- 实现 HandlerInterceptor
创建一个类实现 HandlerInterceptor 接口,并在 preHandle 方法中设置响应头以实现跨域。
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")// 拦截所有的请求
.allowedOrigins("*")// 可跨域的域名,*为所有
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允许跨域的方法,可以单独配置
.maxAge(3600);
}
}
- 重写 WebMvcConfigurer(全局跨域)
@Configuration
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")// 拦截所有的请求
.allowedOrigins("*")// 可跨域的域名,*为所有
.allowCredentials(true)
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允许跨域的方法,可以单独配置
.maxAge(3600);
}
}
- 使用@CrossOrigin注解 (局部跨域)
- 使用自定义filter实现跨域
创建一个类实现 javax.servlet.Filter 接口,并在 doFilter 方法中设置响应头以实现跨域。
@WebFilter
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "http://example.com");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
response.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(req, res);
}
// ...
}
注意:使用 Filter 实现跨域时,Filter 会拦截所有请求,而不仅仅是跨域请求。因此,在设置响应头时需要谨慎,避免影响其他请求的正常处理。如果需要更细粒度的控制,可以考虑使用 @CrossOrigin 注解或拦截器来实现。
- 在响应头中添加 Access-Control-Allow-Origin 等字段,如果希望允许所有域名访问 API,可以将值设置为 *:
response.setHeader("Access-Control-Allow-Origin", "http://example.com")
- 使用 Nginx 配置
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
if ($request_method = 'OPTIONS') {
return 204;
}
}
如果使用了带有身份验证信息的请求,例如带有 Cookie 的请求,那么需要将 Access-Control-Allow-Credentials 字段设置为 true,表示允许发送身份验证信息。例如:
add_header 'Access-Control-Allow-Credentials' 'true';
- 配置 Gateway 的路由
- id: my_route
uri: http://localhost:8080
predicates:
- Path=/api/**
filters:
- RewritePath=/api/(?<segment>.*), /$\{segment}
- AddResponseHeader=Access-Control-Allow-Origin:http://example.com
- AddResponseHeader=Access-Control-Allow-Methods:GET, POST, PUT, DELETE
- AddResponseHeader=Access-Control-Allow-Headers:Content-Type, Authorization
- AddResponseHeader=Access-Control-Allow-Credentials:true
这将允许来自 http://example.com 的跨域请求访问 Gateway 中的 API。
如果使用了带有身份验证信息的请求,例如带有 Cookie 的请求,那么需要将 Access-Control-Allow-Credentials 字段设置为 true,表示允许发送身份验证信息。例如:
- AddResponseHeader=Access-Control-Allow-Credentials:true