消息队列篇--通信协议篇--MQTT(通配式主题,消息服务质量Qos,EMQX的Broker,MqttClient示例,MQTT报文等)

MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息协议。它基于发布/订阅模式,专为低带宽、高延迟或不可靠网络设计。它主要用于物联网(IoT)设备之间的通信,但也广泛应用于其他需要高效消息传递的场景。

特点:

  • 轻量级,头部开销小,适合资源受限的设备。
  • 支持发布/订阅模式,适合一对多的消息传递。
  • 支持QoS(服务质量)级别,确保消息的可靠传递。
  • 支持持久会话,断线后可以恢复未完成的消息传递。
  • 支持TLS/SSL加密,确保安全传输。

适用场景:

  • 物联网设备之间的通信。
  • 传感器网络和智能设备的管理。
  • 低带宽、低功耗的嵌入式系统。

1、基本概念

(1)、发布/订阅模型

MQTT使用发布/订阅模型进行通信,而不是传统的客户端-服务器请求/响应模型。这种模型的优点在于解耦了消息的生产者和消费者。
主要涉及3个概念:

  • 发布者(Publisher):发送消息到特定主题(Topic)。
  • 订阅者(Subscriber):订阅特定主题并接收该主题的所有消息。
  • 代理(Broker):负责管理和分发消息的中间件。

(2)、主题(Topic)

主题是消息的分类方式,类似于文件系统中的路径。主题可以使用斜杠/分隔层次结构,例如home/livingroom/temperature。

主题支持通配符订阅:

  • 单层通配符+:匹配单个层级的主题(即:+只能匹配一个单词),如home/+/temperature可以匹配home/livingroom/temperature和home/kitchen/temperature。
  • 多层通配符* :匹配多个层级的主题(即:*可以匹配多个单词),如home/*可以匹配 home/livingroom和home/kitchen/light等。

(3)、QoS(Quality of Service)

QoS定义了消息传递的服务质量级别,有三种级别。
级别:

  • QoS 0:最多一次(At most once)。消息可能丢失,但不会重复发送。
  • QoS 1:至少一次(At least once)。消息保证送达,但可能会重复发送。
  • QoS 2:恰好一次(Exactly once)。消息保证仅送达一次,可靠性最高。

2、MQTT协议的工作流程

原理示例图:
在这里插入图片描述

(1)、连接建立

客户端通过TCP连接到Broker,并发送CONNECT消息。

CONNECT消息包含以下字段:

  • Client Identifier (ClientId):唯一标识客户端。
  • Clean Session:决定是否清除会话状态。
  • Will Topic:遗嘱消息的主题。
  • Will Message:遗嘱消息的内容。
  • Username/Password:用于认证。

Broker收到CONNECT消息后,返回CONNACK消息确认连接成功或失败。

(2)、订阅主题

客户端向Broker发送SUBSCRIBE消息以订阅一个或多个主题。SUBSCRIBE消息包含主题列表和对应的QoS级别。

Broker返回SUBACK消息确认订阅成功,并指明每个主题的实际QoS级别。

(3)、发布消息

客户端向Broker发送PUBLISH消息以发布消息到指定主题。

PUBLISH消息包含以下字段:

  • Topic Name:消息发布的主题。
  • Payload:消息内容。
  • QoS:服务质量级别。
  • Retain Flag:是否保留消息。

Broker将消息转发给所有订阅了该主题的客户端。

(4)、取消订阅

客户端向Broker发送UNSUBSCRIBE消息以取消订阅一个或多个主题。UNSUBSCRIBE消息包含主题列表。

Broker返回UNSUBACK 消息确认取消订阅成功。

(5)、断开连接

客户端向Broker发送DISCONNECT消息断开连接。如果Clean Session设置为true,Broker将清除与该客户端相关的会话状态。

3、MQTT协议的优势

(1)、轻量级
MQTT的头部非常小,通常只有2字节,这使得它非常适合资源受限的设备,如传感器和嵌入式系统。
(2)、高效
MQTT使用发布/订阅模型,减少了不必要的网络流量和计算资源消耗。同时,QoS机制确保了消息的可靠传输。
(3)、可扩展性
MQTT支持大规模分布式系统中的消息传递。通过使用Broker,可以在不同地理位置的设备之间实现高效的通信。
(4)、安全性
MQTT支持多种安全机制。
例如:

  • TLS/SSL:加密传输通道。
  • 用户名/密码认证:基于凭证的身份验证。
  • ACL(Access Control List):细粒度的权限控制。

4、MQTT实际应用案例

(1)、物联网设备管理
在智能家居、工业自动化等场景中,MQTT广泛应用于设备状态监控、远程控制和数据采集。例如,智能温控器可以发布当前温度到home/livingroom/temperature主题,用户可以通过订阅该主题获取最新温度数据。
(2)、移动应用
移动应用可以使用MQTT实现即时通讯功能。由于其轻量级特性,即使在网络条件不佳的情况下,也能保证消息的及时传递。
(3)、边缘计算
边缘计算设备可以使用MQTT实现与云端的高效通信。例如,在自动驾驶汽车中,车载传感器可以将实时数据发布到云端进行分析和处理。

5、MQTT实现与工具

(1)、MQTT Broker

常见的MQTT Broker实现有:
- EMQ X:高性能、可扩展的MQTT Broker。(最常用)

  • Mosquitto:开源、轻量级的MQTT Broker。
  • HiveMQ:企业级MQTT Broker,支持集群部署。

(2)、MQTT客户端库

主流编程语言都有相应的MQTT客户端库。
例如:

  • Java:Eclipse Paho
  • Python:paho-mqtt
  • JavaScript:mqtt.js

(3)、MQTT测试工具

常用的MQTT测试工具有:

  • MQTTX:图形化MQTT客户端,适合手动测试。
  • mosquitto_pub/mosquitto_sub:命令行工具,适合脚本化测试。

6、代码示例

在Spring Boot应用中集成MQTT,通常使用Eclipse Paho的MQTT客户端库。

(1)、添加依赖

<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- Eclipse Paho MQTT Client --><dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.client.mqttv3</artifactId><version>1.2.5</version></dependency><!-- Lombok (可选) --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency>
</dependencies>

(2)、MQTT发布者

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;public class MqttPublisher {public static void main(String[] args) {String broker = "tcp://broker.hivemq.com:1883";    // emq服务器地址信息String clientId = "publisher-client";    // 客户端的唯一标识符,尽量设置唯一String topic = "home/livingroom/message";   // 主题try {// 创建客户端实例MqttClient client = new MqttClient(broker, clientId);// 设置连接选项MqttConnectOptions options = new MqttConnectOptions();options.setCleanSession(true);  // 表示每次连接时清除会话状态。// 设置回调函数client.setCallback(new MqttCallback() {@Overridepublic void connectionLost(Throwable cause) {  //方法在连接丢失时调用System.out.println("Connection lost: " + cause.getMessage());}@Overridepublic void messageArrived(String topic, MqttMessage message) throws Exception {   // 方法在收到消息时调用。System.out.println("Message arrived from topic: " + topic + " -> " + new String(message.getPayload()));}@Overridepublic void deliveryComplete(IMqttDeliveryToken token) { // 方法在消息发送完成时调用。System.out.println("Delivery complete: " + token.isComplete());}});// 连接到Brokerclient.connect(options);System.out.println("Connected to broker");// 创建消息String content = "我想吃火锅,速去!!";MqttMessage message = new MqttMessage(content.getBytes());message.setQos(1); // 设置 QoS 级别为 1// 发布消息client.publish(topic, message);System.out.println("Message published");// 断开连接client.disconnect();System.out.println("Disconnected");} catch (MqttException me) {System.out.println("Reason " + me.getReasonCode());System.out.println("msg " + me.getMessage());System.out.println("loc " + me.getLocalizedMessage());System.out.println("cause " + me.getCause());System.out.println("excep " + me);me.printStackTrace();}}
}

(3)、MQTT消费者

import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;public class MqttSubscriber {public static void main(String[] args) {String broker = "tcp://broker.hivemq.com:1883";String clientId = "subscriber-client";String topic = "home/livingroom/message";try {// 创建客户端实例MqttClient client = new MqttClient(broker, clientId);// 设置连接选项MqttConnectOptions options = new MqttConnectOptions();options.setCleanSession(true);// 设置回调函数client.setCallback(new MqttCallback() {@Overridepublic void connectionLost(Throwable cause) {System.out.println("Connection lost: " + cause.getMessage());}@Overridepublic void messageArrived(String topic, MqttMessage message) throws Exception {System.out.println("Message arrived from topic: " + topic + " -> " + new String(message.getPayload()));}@Overridepublic void deliveryComplete(IMqttDeliveryToken token) {System.out.println("Delivery complete: " + token.isComplete());}});// 连接到 Brokerclient.connect(options);System.out.println("Connected to broker");// 订阅主题int qos = 1; // 设置QoS级别为 1client.subscribe(topic, qos);    // 订阅主题System.out.println("Subscribed to topic: " + topic);// 保持程序运行以接收消息while (true) {Thread.sleep(1000);}} catch (MqttException | InterruptedException me) {System.out.println("Reason " + me.getReasonCode());System.out.println("msg " + me.getMessage());System.out.println("loc " + me.getLocalizedMessage());System.out.println("cause " + me.getCause());System.out.println("excep " + me);me.printStackTrace();}}
}

7、QoS(Quality of Service)可靠性原理

MQTT的QoS机制确保消息在不同网络条件下以不同的可靠性级别进行传输。QoS分为三个级别:0、1和2,每个级别提供不同程度的消息传递保证。

(1)、QoS 0–最多一次(At most once)

  • 描述:消息发送后不进行确认,可能会丢失。
  • 适用场景:适用于对数据丢失容忍度较高的应用,如环境传感器的数据采集,偶尔丢失一条数据不会影响整体分析结果。
  • 工作原理:
    • 发布者将消息发送到Broker。
    • Broker收到消息后直接转发给订阅者。
    • 没有确认机制,因此消息可能丢失。

流程示例图:
在这里插入图片描述

(2)、QoS 1–至少一次(At least once)

  • 描述:消息至少会被传递一次,但可能会重复传递。
  • 适用场景:适用于对数据丢失敏感但可以容忍重复的应用,如智能设备的状态报告。
  • 工作原理:
    • 发布者发送消息时附带一个消息ID。
    • Broker收到消息后,向发布者发送PUBACK确认消息已接收。
    • 如果发布者在一定时间内没有收到PUBACK,它会重新发送消息,直到收到确认。
    • 订阅者接收到消息后也会向Broker发送确认(PUBACK),Broker再次确认消息已被处理。
    • 可能导致消息重复,但不会丢失。

示例图:
在这里插入图片描述

(3)、QoS 2–恰好一次(Exactly once)

  • 描述:消息只会被传递一次,确保无重复和无丢失。
  • 适用场景:适用于对数据准确性要求极高的应用,如金融交易系统或关键任务控制系统。
  • 工作原理:
    • 发布者发送消息时附带一个消息ID。
    • Broker收到消息后,向发布者发送PUBREC确认消息已接收。
    • 发布者收到PUBREC后,发送PUBREL请求释放消息。
    • Broker收到PUBREL后,发送PUBCOMP确认消息已完成,并将消息转发给订阅者。
    • 订阅者接收到消息后,向Broker发送PUBREC确认消息已接收,Broker再次确认消息已被处理。
    • 这种机制确保消息只会被传递一次,不会重复也不会丢失。

示例图:
在这里插入图片描述

注意:
QoS 2虽然消息处理是最好的,但是消耗也是最厉害的,性能也比较差,如果非必要,不建议设置这么高的消息级别。

8、订阅主题和发布消息的QoS设置

在MQTT中,订阅主题和发布消息都可以设置QoS级别。它们之间的关系决定了实际消息传递的QoS级别。

(1)、订阅者的QoS设置

当客户端订阅某个主题时,它可以指定一个QoS级别。这表示该客户端希望从该主题接收到的消息的最低QoS级别。

(2)、发布者的QoS设置

当客户端发布消息到某个主题时,它也可以指定一个QoS级别。这表示该消息将以何种QoS级别传递给Broker。

(3)、实际QoS级别的确定

实际传递给订阅者的QoS级别由以下规则决定:

  • 订阅者的QoS >发布者的QoS:实际传递的QoS级别为发布者的QoS级别。
  • 订阅者的QoS <=发布者的QoS:实际传递的QoS级别为订阅者的QoS级别。
    简单说:
    以qos较小的为准,提供性能更加的服务。

例如:

  • 订阅者QoS = 0,无论发布者设置的QoS是什么,订阅者都将按QoS 0接收消息。
  • 订阅者QoS = 1,如果发布者设置的QoS是0,1,2,订阅者将按QoS 1接收消息;
  • 订阅者QoS = 2,只有当发布者设置的QoS是2 时,订阅者才能按QoS 2接收消息;否则,订阅者将按发布者的QoS级别接收消息。

9、MQTT报文格式详解

MQTT(Message Queuing Telemetry Transport)协议使用一种紧凑的二进制报文格式进行通信。MQTT报文分为多种类型,每种类型的报文都有其特定的结构和用途。

(1)、MQTT报文结构

每个MQTT报文由以下部分组成:

  • 固定报头(Fixed Header):所有MQTT报文都包含固定报头。
  • 可变报头(Variable Header):某些类型的报文包含可变报头。
  • 有效载荷(Payload):某些类型的报文包含有效载荷。
1、固定报头(Fixed Header)

固定报头是每个 MQTT 报文的必需部分,它包含以下字段:

  • 报文类型(Type):4位,表示报文的类型,如CONNECT、PUBLISH、SUBSCRIBE等。
  • 标志位(Flags):4位,用于指定报文的具体行为。
  • 剩余长度(Remaining Length):表示可变报头和有效载荷的总长度。
2、可变报头(Variable Header)

可变报头的内容取决于报文类型。例如,PUBLISH报文的可变报头包含主题名称和消息ID。

3、有效载荷(Payload)

有效载荷的内容也取决于报文类型。例如,PUBLISH报文的有效载荷包含实际的消息内容。

(2)、PUBLISH报文示例

假设发送一条消息:“我想吃火锅,速去!!”,可以通过PUBLISH报文来实现。

1、固定报头示例
  • 报文类型:0x30(PUBLISH报文)
  • 标志位:根据QoS和其他标志位设置
  • 剩余长度:计算可变报头和有效载荷的总长度

假设QoS = 0,不保留消息,则固定报头为0x30。

2、可变报头示例
  • 主题名称(Topic Name):消息发布的主题,例如home/livingroom/message
  • 消息ID(Message ID):仅当QoS > 0时需要
3、有效载荷示例

有效载荷包含实际的消息内容,即 “我想吃火锅,速去!!”。

4、完整报文示例
Fixed Header: 0x30 0x24
Variable Header:Topic Name Length MSB: 0x00Topic Name Length LSB: 0x1CTopic Name Content: 0x68 0x6F 0x6D 0x65 0x2F 0x6C 0x69 0x76 0x69 0x6E 0x67 0x72 0x6F 0x6F 0x6D 0x2F 0x6D 0x65 0x73 0x73 0x61 0x67 0x65
Payload:0xE6 0x88 0x91 0xE6 0x83 0xB3 0xE5 0x90 0x83 0xE7 0x82 0x8A 0xE9 0xA3 0x9F 0xEF 0xBC 0x8C 0xE9 0x80 0x9F 0xE5 0x8E 0xBB 0xEF 0xBC 0x81 0xEF 0xBC 0x81

解释:
Fixed Header为固定报头。
Variable Header为可变报头。
Payload为有效载荷。

5、消费者接收报文

消费者(订阅者)接收到的报文与发布者发送的报文相同。订阅者需要解析固定报头、可变报头和有效载荷以获取消息内容。

解析步骤:
(1)、读取固定报头:确定报文类型和剩余长度。
(2)、读取可变报头:获取主题名称的长度和内容。
(3)、读取有效载荷:获取实际的消息内容。

10、总结

MQTT是一种高效、可靠的轻量级消息协议,特别适用于物联网和移动应用领域。通过发布/订阅模型和 QoS 机制,MQTT 提供了灵活且强大的消息传递能力。无论是简单的设备状态监控还是复杂的分布式系统,MQTT 都能提供有效的解决方案。

乘风破浪!Dare to Be!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/8059.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

dmfldr实战

dmfldr实战 本文使用达梦的快速装载工具&#xff0c;对测试表进行数据导入导出。 新建测试表 create table “BENCHMARK”.“TEST_FLDR” ( “uid” INTEGER identity(1, 1) not null , “name” VARCHAR(24), “begin_date” TIMESTAMP(0), “amount” DECIMAL(6, 2), prim…

基于OSAL的嵌入式裸机事件驱动框架——消息队列osal_msg

参考B站up主【架构分析】嵌入式祼机事件驱动框架 感谢大佬分享 消息队列 消息分为hdr和bdy&#xff0c;把消息的头dhr和内容bdy做了一个分离的设计 dhr包括指向下一个消息的指针next&#xff0c;len在创建消息的时候使用&#xff0c;dest_id即目标任务&#xff0c;将消息和任务…

关于MySQL InnoDB存储引擎的一些认识

文章目录 一、存储引擎1.MySQL中执行一条SQL语句的过程是怎样的&#xff1f;1.1 MySQL的存储引擎有哪些&#xff1f;1.2 MyIsam和InnoDB有什么区别&#xff1f; 2.MySQL表的结构是什么&#xff1f;2.1 行结构是什么样呢&#xff1f;2.1.1 NULL列表&#xff1f;2.1.2 char和varc…

单相可控整流电路——单相桥式全控整流电路

以下是关于单相桥式整流电路的介绍&#xff1a; 电路构成&#xff08;带阻性负载的工作情况&#xff09; - 二极管&#xff1a;是电路0的核心元件&#xff0c;通常采用四个同型号或根据需求选择不同型号的二极管&#xff0c;如1N4001、1N4007等&#xff0c;如图Vt1和Vt4是一对…

Linux(Centos、Ubuntu) 系统安装jenkins服务

该文章手把手演示在Linux系统下如何安装jenkins服务、并自定义jenkins数据文件位置、以及jenkins如何设置国内镜像源加速&#xff0c;解决插件下载失败问题 安装方式&#xff1a;war包安装 阿里云提供的war下载源地址&#xff1a;https://mirrors.aliyun.com/jenkins/war/?s…

力扣算法题——11.盛最多水的容器

目录 &#x1f495;1.题目 &#x1f495;2.解析思路 本题思路总览 借助双指针探索规律 从规律到代码实现的转化 双指针的具体实现 代码整体流程 &#x1f495;3.代码实现 &#x1f495;4.完结 二十七步也能走完逆流河吗 &#x1f495;1.题目 &#x1f495;2.解析思路…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】 1.3 广播机制:维度自动扩展的黑魔法

1.3 《广播机制&#xff1a;维度自动扩展的黑魔法》 前言 NumPy 的广播机制是 Python 科学计算中最强大的工具之一&#xff0c;它允许不同形状的数组进行运算&#xff0c;而无需显式地扩展数组的维度。这一机制在实际编程中非常有用&#xff0c;但初学者往往对其感到困惑。在…

Semantic Kernel - Kernel理解

目录 一、关于Kernel 二、案例实战 三、运行截图 一、关于Kernel 微软的 Semantic Kernel 项目中,Semantic Kernel 是一个工具框架,旨在使得开发人员能够更容易地将大语言模型(如GPT)集成到不同的应用中。它通过提供一组接口、任务模板和集成模块,使开发者能够轻松地设计…

【MySQL】--- 复合查询 内外连接

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏&#xff1a; MySQL &#x1f3e0; 基本查询回顾 假设有以下表结构&#xff1a; 查询工资高于500或岗位为MANAGER的雇员&#xff0c;同时还要满足他们的姓名首字母为…

Qt Designer and Python: Build Your GUI

1.install pyside6 2.pyside6-designer.exe 发送到桌面快捷方式 在Python安装的所在 Scripts 文件夹下找到此文件。如C:\Program Files\Python312\Scripts 3. 打开pyside6-designer 设计UI 4.保存为simple.ui 文件&#xff0c;再转成py文件 用代码执行 pyside6-uic.exe simpl…

openlayer getLayerById 根据id获取layer图层

背景&#xff1a; 在项目中使用getLayerById获取图层&#xff0c;这个getLayerById()方法不是openlayer官方文档自带的&#xff0c;而是自己封装的一个方法&#xff0c;这个封装的方法的思路是&#xff1a;遍历所有的layer&#xff0c;根据唯一标识【可能是id&#xff0c;也可能…

Qt 控件与布局管理

1. Qt 控件的父子继承关系 在 Qt 中&#xff0c;继承自 QWidget 的类&#xff0c;通常会在构造函数中接收一个 parent 参数。 这个参数用于指定当前空间的父控件&#xff0c;从而建立控件间的父子关系。 当一个控件被设置为另一控件的子控件时&#xff0c;它会自动成为该父控…

SOME/IP--协议英文原文讲解1

前言 SOME/IP协议越来越多的用于汽车电子行业中&#xff0c;关于协议详细完全的中文资料却没有&#xff0c;所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块&#xff1a; 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 一、SOM…

Ansible自动化运维实战--script、unarchive和shell模块(6/8)

文章目录 一、script模块1.1、功能1.2、常用参数1.3、举例 二、unarchive模块2.1、功能2.2、常用参数2.3、举例 三、shell模块3.1、功能3.2、常用参数3.3、举例 一、script模块 1.1、功能 Ansible 的 script 模块允许你在远程主机上运行本地的脚本文件&#xff0c;其提供了一…

【模型】RNN模型详解

1. 模型架构 RNN&#xff08;Recurrent Neural Network&#xff09;是一种具有循环结构的神经网络&#xff0c;它能够处理序列数据。与传统的前馈神经网络不同&#xff0c;RNN通过将当前时刻的输出与前一时刻的状态&#xff08;或隐藏层&#xff09;作为输入传递到下一个时刻&…

《FreqMamba: 从频率角度审视图像去雨问题》学习笔记

paper&#xff1a;FreqMamba: Viewing Mamba from a Frequency Perspective for Image Deraining GitHub&#xff1a;GitHub - aSleepyTree/FreqMamba 目录 摘要 1、介绍 2、相关工作 2.1 图像去雨 2.2 频率分析 2.3 状态空间模型 3、方法 3.1 动机 3.2 预备知识 3…

iic、spi以及uart

何为总线&#xff1f; 连接多个部件的信息传输线&#xff0c;是部件共享的传输介质 总线的作用&#xff1f; 实现数据传输&#xff0c;即模块之间的通信 总线如何分类&#xff1f; 根据总线连接的外设属于内部外设还是外部外设将总线可以分为片内总线和片外总线 可分为数…

Android WebView 中网页被劫持的原因及解决方案

文章目录 一、原因分析二、解决方案一览三、解决方案代码案例3.1 使用 HTTPS3.2 验证 URL3.3 禁用 JavaScript3.4 使用安全的 WebView 设置3.5 监控网络请求3.6 使用安全的 DNS 四、案例深入分析4.1 问题4.2 分析 五、结论 在 Android 应用开发中&#xff0c;WebView 是一个常用…

Linux——网络(udp)

文章目录 目录 文章目录 前言 一、upd函数及接口介绍 1. 创建套接字 - socket 函数 2. 绑定地址和端口 - bind 函数 3. 发送数据 - sendto 函数 4. 接收数据 - recvfrom 函数 5. 关闭套接字 - close 函数 二、代码示例 1.服务端 2.客户端 总结 前言 Linux——网络基础&#xf…

C语言学习强化

前言 数据的逻辑结构包括&#xff1a; 常见数据结构&#xff1a; 线性结构&#xff1a;数组、链表、队列、栈 树形结构&#xff1a;树、堆 图形结构&#xff1a;图 一、链表 链表是物理位置不连续&#xff0c;逻辑位置连续 链表的特点&#xff1a; 1.链表没有固定的长度…