当前位置: 首页 > article >正文

前端面试灵魂提问-计网(2)

1、websocket 为什么全双工?

1.1 WebSocket是什么

WebSocket 是一种通信协议,它在客户端和服务器之间建立持久的全双工连接。全双工意味着数据可以双向流动,即客户端可以向服务器发送消息,服务器也可以向客户端发送消息,而无需客户端或服务器先发起请求。

这种全双工的设计有几个优点:

  1. 实时性: 全双工通信允许双方实时地发送和接收数据,这对于实时性要求高的应用场景非常重要,比如在线聊天、在线游戏等。

  2. 减少延迟: 与传统的基于请求-响应模式的通信相比,WebSocket 的全双工通信减少了请求和响应之间的延迟。服务器和客户端可以直接推送消息而无需等待请求。

  3. 减少网络流量: 相较于轮询等方式,WebSocket 采用了更为高效的通信方式,可以减少不必要的数据传输,降低网络流量。

  4. 资源效率: WebSocket 连接是持久的,不需要频繁地断开和重新建立连接。这减少了在每次通信中都要建立连接的开销,提高了资源的利用效率。

WebSocket 是建立在 TCP 连接之上的,通过握手等机制,可以在客户端和服务器之间建立一个长期有效的连接,实现双方的实时数据传输。

1.2 WebSocket如何实现全双工

WebSocket 通过协议的握手过程、保持连接的机制以及数据帧的使用,实现了全双工通信。在前端开发中,通常会使用 WebSocket API 来处理 WebSocket 连接,而后端服务器也需要支持 WebSocket 协议。

  1. 握手过程: WebSocket 连接是通过 HTTP 协议进行握手的。客户端发送一个 HTTP 请求,包含一个包含 WebSocket 版本信息的特殊头部字段,表明希望升级为 WebSocket 连接。这个头部字段是 Upgrade,并且携带的值是 websocket。此外,还有一个 Connection 头部字段,它的值也是 Upgrade。服务器在接收到这个请求后,如果同意升级为 WebSocket 连接,就会返回一个包含一些信息的 HTTP 响应,然后连接就升级为 WebSocket。如果不同意升级为 WebSocket 连接,它会返回一个包含适当状态码的 HTTP 响应,状态码 400 Bad Request 或 403 Forbidden 会被使用,并在 Connection 头部字段中保持为 Upgrade。客户端的 WebSocket 对象会触发 close 事件。

  2. 保持连接: 握手成功后,WebSocket 连接就变成了全双工的,可以在连接保持的情况下双向传输数据。这与传统的 HTTP 请求-响应模型不同,WebSocket 连接是持久的,不需要在每次通信时都重新建立连接。

  3. 数据帧: WebSocket 使用数据帧来在客户端和服务器之间传递信息。数据帧是 WebSocket 协议中的最小数据单位,可以包含文本、二进制数据等。每个数据帧都有一个标志位,用于指示这个帧是一个消息的开始、结束,还是中间的一部分。

  4. 双向通信: 一旦 WebSocket 连接建立起来,双方可以通过发送数据帧实现双向通信。无论是客户端还是服务器,都可以随时发送消息给对方,而不需要等待对方的请求。这使得实时的、双向的通信成为可能。

1.3 前端开发使用 WebSocket API

1、创建 WebSocket 对象: 使用 new WebSocket(url) 来创建一个 WebSocket 对象,其中 url 是 WebSocket 服务器的地址。例如

const socket = new WebSocket('ws://example.com/socket');

2、定义事件处理程序: WebSocket 对象支持一系列事件,包括 openmessageerrorclose。你可以通过定义相应的事件处理程序来处理这些事件。

socket.addEventListener('open', (event) => {
    console.log('WebSocket连接已打开');
});

socket.addEventListener('message', (event) => {
    console.log('接收到消息:', event.data);
});

socket.addEventListener('error', (event) => {
    console.error('WebSocket发生错误:', event);
});

socket.addEventListener('close', (event) => {
    console.log('WebSocket连接已关闭:', event);
});

3、发送和接收消息: 使用 send 方法向服务器发送消息,通过监听 message 事件来接收服务器发送的消息。

// 发送消息
socket.send('Hello, server!');

// 接收消息已在上述的 'message' 事件处理程序中演示

发送二进制文件

// 监听连接打开事件
socket.addEventListener('open', (event) => {
    console.log('WebSocket 连接已打开');

    // 创建一个 ArrayBuffer 对象
    const buffer = new ArrayBuffer(16);

    // 使用 DataView 将数据写入 ArrayBuffer
    const view = new DataView(buffer);
    view.setInt32(0, 42);

    // 发送二进制数据
    socket.send(buffer);
});

4、关闭连接: 使用 close 方法关闭 WebSocket 连接。

// 关闭连接
socket.close();

2、 websockt同时发数据,如何保证收到的数据是当前的

在 WebSocket 中,发送多条消息并确保它们按照特定的顺序到达是一个常见的需求。WebSocket 的全双工性质允许你同时发送多条消息,但它们的顺序在接收端可能不一定按照发送的顺序到达,因为消息的发送和接收是异步的。

消息附加序列号: 在每条消息中附加一个唯一的序列号,接收端在收到消息时根据序列号对消息进行排序。在实际应用中,可以在消息中附加时间戳或序列号,以便于接收端正确排序。

let sequenceNumber = 0;

function sendMessage(message) {
    const messageWithSequence = {
        sequence: sequenceNumber++,
        content: message
    };

    socket.send(JSON.stringify(messageWithSequence));
}

3、webscoket 和keep-alive的区别,有了 HTTP 的keep-alive为什么还要websocket

在网页加载资源时可以使用 Keep-Alive 提高效率,而在需要实时通信的功能上使用 WebSocket 提供更好的用户体验。

HTTP 协议中使用 Content-Length 头部或者 Transfer-Encoding: chunked 头部来指示消息主体的长度或者以分块方式传输。当服务器端通过这些方式告知消息的结束时,客户端就能够识别出一个请求已经结束。

WebSocket 在协议层面已经提供了消息的边界,服务器和客户端能够准确判断消息的开始和结束。

TCP 的 Keep-Alive 是在 TCP 协议层面实现的,用于检测连接是否仍然活跃。

3.1 相同点:建立持久连接

  1. Keep-Alive:

    • 目的: HTTP Keep-Alive 是一种机制,用于在单个 TCP 连接上重用多个 HTTP 请求和响应,以减少连接的建立和关闭的开销。

    • 工作原理: 默认情况下,每个 HTTP 请求都会创建一个新的 TCP 连接,然后在响应完成后关闭连接。使用 Keep-Alive,可以在同一连接上发送多个请求和接收多个响应,而不必为每个请求重新建立连接。

    • 适用场景: 主要用于提高 HTTP 请求的效率,减少资源消耗,特别是在需要多次请求的情况下,如加载网页上的多个资源文件。

  2. WebSocket:

    • 目的: WebSocket 是一种全双工通信协议,旨在提供实时、双向的通信能力,适用于需要低延迟、高实时性的应用场景。

    • 工作原理: WebSocket 通过单个 TCP 连接实现全双工通信,连接建立后保持打开状态,允许服务器和客户端在任何时候都能发送和接收数据。

    • 适用场景: 主要用于实时通信,例如在线聊天、实时协作、在线游戏等场景。相较于 HTTP,WebSocket 更适合处理频繁的双向通信需求

3.2 区别

  1. 性能: WebSocket 在处理实时通信时更为高效,因为它是一个持久连接,而且不需要在每次通信时重新建立连接。相比之下,Keep-Alive 只是在短时间内重用连接,但仍需要在每次通信时发起新的请求。

  2. 推送通知: WebSocket 更适用于服务器主动向客户端推送消息的场景,而 Keep-Alive 更适用于客户端主动向服务器发起请求的场景。

  3. 实时性: WebSocket 提供更低延迟和更高的实时性,适用于需要及时传递信息的应用。Keep-Alive 可以减少连接建立和关闭的开销,但无法提供实时的双向通信。

4、 以下是 TCP 使用的一些机制来减少丢包的可能性:

  1. 序号和确认: TCP 在每个数据包上都附加一个序号,接收方在收到数据包后会发送一个确认,表明它已经成功接收了该数据包。如果发送方在一定时间内未收到确认,它会重新发送相同的数据包,确保数据的正确到达。

  2. 重传机制: 如果发送方在合理的时间内未收到确认,它会假定数据包丢失,并进行重传。这确保了即使某个数据包在传输过程中丢失,它仍然有机会重新发送。

  3. 流量控制: TCP 使用滑动窗口机制来进行流量控制,确保发送方不会发送过多的数据导致接收方无法处理。如果接收方的缓冲区已满,它可以通知发送方减缓发送速度,从而减少数据包的丢失可能性。

  4. 拥塞控制: TCP 使用拥塞控制算法来避免网络拥塞。当网络出现拥塞时,TCP 会减小发送窗口的大小,降低发送速率,以避免过多的数据包在网络中引起丢失。

  5. 超时和重试: TCP 在发送数据后会设置一个定时器,如果在规定的时间内未收到确认,就会认为数据包丢失,并触发重传机制

4.2 包丢了会怎么办?TCP 重传的条件通常由以下几个因素决定:

  1. 超时: TCP 发送数据后会设置一个定时器(称为超时时间),在等待接收方发送确认时启动。如果超过了超时时间仍未收到确认,发送方就会认为数据丢失,并触发重传机制。

  2. 收到重复的 ACK(确认): 当发送方的某个数据包超时或者丢失时,接收方可能会收到重复的数据包(即重复的序列号)。接收方会发送一个带有已收到的最后一个连续数据包序号的 ACK 给发送方,以告知发送方某些数据包丢失了。发送方接收到这样的 ACK 后,会触发重传丢失的数据包。

  3. 快速重传: TCP 还具有一种称为“快速重传”的机制。当发送方接收到连续的三个相同的 ACK 时,它会立即重传丢失的数据包,而不必等待超时。这种情况表明接收方已经收到了后续的数据包,但中间有一个或多个数据包丢失。

什么是浏览器缓存?缓存分为什么?

浏览器缓存是一种用于临时存储和管理网络资源的机制,目的是提高网页加载性能和用户体验。通过缓存,浏览器可以避免重新下载已经获取过的资源,从而减少加载时间和减轻服务器的负担。

  1. 本地缓存(Local Cache):

    • Memory Cache(内存缓存): 将一些临时性的数据存储在内存中,这样可以快速读取,但生命周期较短。关闭标签页或浏览器时,这些缓存数据会被清除。
    • Disk Cache(磁盘缓存): 将一些持久性的数据存储在硬盘上,生命周期较长。即使关闭浏览器,这些缓存数据也可能被保留。
  2. 网络缓存(Network Cache):

    • Service Worker Cache: 使用 Service Worker 技术,允许网站开发者自定义缓存策略,实现离线访问等高级功能。
    • HTTP 缓存: 存储在浏览器的本地存储中。使用 HTTP 协议中的缓存头部,如 Cache-ControlExpiresLast-ModifiedETag 等,控制浏览器对资源的缓存策略。

http://www.kler.cn/news/162728.html

相关文章:

  • Windows循环检测,直到网络通/断后执行指定命令
  • springboot如何格式化时间
  • 安装以及使用Minio分布式文件系统
  • SQL注入攻击
  • numpy数据读取保存及速度测试
  • Opencv打开图片
  • Java-网络通信总结
  • 掌握VUE中localStorage的使用
  • Gateway:微服务架构中的关键组件
  • ssl什么是公钥和私钥?
  • ES-深入理解倒排索引
  • Docker-compose容器编排与容器监控
  • 基于运算放大器的电压采集电路
  • Elasticsearch:什么是检索增强生成 (RAG)?
  • 【力扣100】7.无重复字符的最长子串
  • leetcode 3. 无重复字符的最长子串
  • Mysql 索引概念回顾
  • 基于java的贪吃蛇小游戏
  • Zabbix 执行自定义key脚本超时timeout while executing a shell script
  • Linux C语言 39-进程间通信IPC之管道
  • 【科学炼丹指南】机器学习最科学、最有效的参数优化全流程实现方法
  • VUE学习一、环境的安装
  • 【力扣100】8.找到字符串中所有字母异位词
  • HarmonyOS通过OpenGL渲染显示yuv数据
  • modbus转profinet网关解决plc插槽号不够用的情况
  • Numpy数组的运算(第7讲)
  • BUUCTF-WEB-刷题记录(2)
  • Netty03-核心组件NioEventLoopGroup解读
  • 使用Rust Rayon库提升程序运行速度
  • Pytest+Allure生成自动化测试报告!