MQTT協議:IoT通信的輕量級選手

文章總結(幫你們節約時間)

  • MQTT協議是一種輕量級的發布/訂閱通信協議。
  • MQTT通信包括連接建立、訂閱、發布和斷開等過程。
  • MQTT基于TCP/IP,其通信過程涉及多種控制包和數據包。
  • ESP32S3可以通過MQTT協議接收消息來控制IO9引腳上的LED。

想象一下,如果互聯網是一個繁忙的城市,那么MQTT就像是一個高效的快遞系統。而傳統HTTP通信?那就是你不得不親自上門取包裹的情況!MQTT(Message Queuing Telemetry Transport)是物聯網世界的通信明星,它輕巧、靈活,特別適合資源受限的設備。這不就像是那種即使在擁擠的小巷里也能靈活穿梭的電動車嗎?

MQTT是什么?

MQTT是一種基于發布/訂閱模式的輕量級消息傳輸協議,專為低帶寬、高延遲或不穩定網絡環境設計。它最初由IBM開發,現已成為物聯網領域的標準協議之一。

想象MQTT就像是一個神奇的廣播站。你不需要直接聯系想要交流的對象,只需對著廣播站(MQTT服務器,也稱為Broker)說:“我要訂閱’天氣頻道’”。之后,任何發布到"天氣頻道"的信息,你都能收到!這種解耦的設計使得設備之間不需要知道彼此的存在,大大簡化了網絡拓撲。

MQTT的核心概念

主題(Topic)

MQTT的主題就像是郵件的地址系統,但更加靈活。主題由層級組成,用斜杠分隔,例如:home/livingroom/temperature

這種層級結構有什么妙處?你可以使用通配符訂閱多個主題!例如,訂閱home/#就能收到家中所有傳感器的數據,而不用一個個地訂閱。這不比傳統的點對點通信方便多了嗎?

QoS(服務質量)

MQTT提供三種服務質量級別:

  • QoS 0:最多一次,“發了就發了,管它收沒收到”
  • QoS 1:至少一次,“我會一直發,直到收到確認”
  • QoS 2:正好一次,“我保證消息只送達一次,不多不少”

這就像是你發送一封重要郵件,QoS決定了你會不會追蹤它、催促它、確認它是否送達。

MQTT通信過程詳解

連接建立過程

想知道MQTT客戶端和服務器之間的第一次"握手"是怎樣的嗎?請看下面的詳細步驟:

  1. TCP連接建立:MQTT建立在TCP/IP協議之上,首先需要完成TCP三次握手:

    • 客戶端發送SYN包(序列號=x)
    • 服務器回復SYN-ACK包(序列號=y,確認號=x+1)
    • 客戶端發送ACK包(確認號=y+1)
  2. CONNECT包發送:TCP連接建立后,客戶端發送CONNECT包,包含:

    • 客戶端ID
    • 用戶名和密碼(如果需要認證)
    • 保持連接的時間間隔(Keep Alive)
    • 清除會話標志(Clean Session)
    • 遺囑信息(Will Message,在客戶端異常斷開時發送的消息)
  3. CONNACK響應:服務器回復CONNACK包,告知連接是否成功,包含:

    • 連接返回碼(0表示成功,其他值表示各種錯誤)
    • 會話狀態標志(指示是否有上一個會話)

想象這個過程就像是你走進一個俱樂部,先向保安出示會員卡(TCP連接),然后向接待員登記你的信息(CONNECT),最后接待員確認你可以進入并告訴你你的會員狀態(CONNACK)。

發布/訂閱過程

  1. 訂閱過程

    • 客戶端發送SUBSCRIBE包,指定要訂閱的主題和QoS級別
    • 服務器回復SUBACK包,確認訂閱并返回授予的QoS級別
  2. 發布過程

    • 發布者發送PUBLISH包,包含主題、消息內容和QoS級別
    • 如果QoS > 0,則需要額外的確認包(PUBACK、PUBREC、PUBREL、PUBCOMP)
  3. QoS 1的消息流

    • 發布者→PUBLISH→服務器
    • 服務器→PUBACK→發布者
    • 服務器→PUBLISH→訂閱者
    • 訂閱者→PUBACK→服務器
  4. QoS 2的消息流

    • 發布者→PUBLISH→服務器
    • 服務器→PUBREC→發布者
    • 發布者→PUBREL→服務器
    • 服務器→PUBCOMP→發布者
    • 服務器→PUBLISH→訂閱者
    • 訂閱者→PUBREC→服務器
    • 服務器→PUBREL→訂閱者
    • 訂閱者→PUBCOMP→服務器

看到這些確認過程,是不是覺得QoS 2有點繁瑣?但這正是為了保證消息"正好一次"傳遞的代價!就像快遞公司為了確保貴重包裹安全送達,會要求你簽名、拍照、確認收貨一樣。

保持連接與斷開

  • PINGREQ/PINGRESP:客戶端定期發送心跳包,服務器回應以保持連接活躍
  • DISCONNECT:客戶端發送斷開連接的請求,然后關閉TCP連接

這就像是你在圖書館學習,偶爾舉手讓管理員知道你還在(PING),最后向管理員示意你要離開(DISCONNECT)。

MQTT底層TCP數據包分析

當MQTT協議工作時,TCP層都發生了什么呢?讓我們揭開這個神秘的面紗:

  1. TCP連接建立(三次握手):

    客戶端 -> [SYN] -> 服務器
    客戶端 <- [SYN, ACK] <- 服務器
    客戶端 -> [ACK] -> 服務器
    
  2. MQTT CONNECT包

    TCP頭部:源端口: 隨機端口(如43251)目標端口: 1883(標準MQTT端口)序列號: x確認號: y標志: PSH, ACKMQTT數據:包類型: CONNECT (1)剩余長度: 可變協議名: "MQTT"協議級別: 4(MQTT v3.1.1)或5(MQTT v5.0)連接標志: 用戶名、密碼、遺囑等標志位保持連接: 通常為60秒客戶端標識符: 如"esp32_client_001"[可選]用戶名、密碼等
    
  3. MQTT PUBLISH包(QoS 1)

    TCP頭部:源端口: 隨機端口目標端口: 1883序列號: x+n確認號: y+m標志: PSH, ACKMQTT數據:包類型: PUBLISH (3)剩余長度: 可變主題長度: 2字節長度前綴主題: 如"home/livingroom/led"包ID: 僅當QoS>0時出現有效載荷: 如"ON"或"OFF"
    

看到這些細節,你是不是更能理解MQTT的工作原理了?這些看似復雜的數據包,本質上就是設備之間傳遞的"便條",告訴對方"我想做什么"或"我已經做了什么"。

ESP32S3使用MQTT控制LED實踐

是時候將理論付諸實踐了!讓我們使用ESP32S3通過MQTT協議來控制一個連接到IO9的LED。

硬件準備

  • ESP32S3開發板
  • LED(連接到IO9)
  • 220歐姆電阻
  • 連接線

軟件準備

  • 安裝Arduino IDE
  • 安裝ESP32S3開發板支持
  • 安裝PubSubClient庫(用于MQTT通信)

代碼實現

#include <WiFi.h>
#include <PubSubClient.h>// WiFi配置
const char* ssid = "你的WiFi名稱";
const char* password = "你的WiFi密碼";// MQTT配置
const char* mqtt_server = "你的MQTT服務器地址";
const int mqtt_port = 1883;
const char* mqtt_client_id = "ESP32S3_LED_Controller";
const char* mqtt_topic = "home/esp32s3/led";// LED引腳
const int ledPin = 9;  // IO9WiFiClient espClient;
PubSubClient client(espClient);void setup_wifi() {delay(10);Serial.println("連接到WiFi...");WiFi.begin(ssid, password);while (WiFi.status() != WL_CONNECTED) {delay(500);Serial.print(".");}Serial.println("WiFi已連接");Serial.print("IP地址: ");Serial.println(WiFi.localIP());
}void callback(char* topic, byte* payload, unsigned int length) {// 將接收的字節數組轉換為字符串String message;for (int i = 0; i < length; i++) {message += (char)payload[i];}Serial.print("收到消息: ");Serial.println(message);// 控制LEDif (message.equals("ON")) {digitalWrite(ledPin, HIGH);Serial.println("LED已打開");} else if (message.equals("OFF")) {digitalWrite(ledPin, LOW);Serial.println("LED已關閉");}
}void reconnect() {while (!client.connected()) {Serial.print("嘗試MQTT連接...");if (client.connect(mqtt_client_id)) {Serial.println("已連接");// 訂閱控制主題client.subscribe(mqtt_topic);} else {Serial.print("連接失敗,錯誤碼=");Serial.print(client.state());Serial.println(" 5秒后重試");delay(5000);}}
}void setup() {pinMode(ledPin, OUTPUT);Serial.begin(115200);setup_wifi();client.setServer(mqtt_server, mqtt_port);client.setCallback(callback);
}void loop() {if (!client.connected()) {reconnect();}// 處理MQTT消息client.loop();
}

實現分析

當我們運行這個程序時,ESP32S3會:

  1. 連接到WiFi網絡
  2. 連接到MQTT服務器
  3. 訂閱home/esp32s3/led主題
  4. 等待控制命令

當我們通過MQTT客戶端(如MQTT Explorer或手機App)發布"ON"或"OFF"消息到home/esp32s3/led主題時,ESP32S3會接收到消息并相應地控制LED。

這個過程中發生的TCP和MQTT通信可以通過Wireshark捕獲。發布"ON"消息時,我們將看到:

  1. MQTT PUBLISH包從發布者到MQTT服務器
  2. MQTT服務器將PUBLISH包轉發給ESP32S3
  3. ESP32S3接收到PUBLISH包,解析內容,發現是"ON"
  4. ESP32S3控制IO9引腳輸出高電平,點亮LED

這就像是我們在微信群(MQTT服務器)里發了一條消息"開燈",而ESP32S3正好在看這個群,看到消息后立即執行了開燈的動作!

MQTT的安全性考慮

在實際應用中,安全性至關重要。MQTT本身并不提供加密,但可以通過以下方式增強安全性:

  1. 使用MQTT over TLS/SSL:使用8883端口而不是標準的1883端口
  2. 客戶端身份驗證:使用用戶名/密碼或客戶端證書
  3. 訪問控制列表(ACL):在服務器端配置,限制客戶端可以發布/訂閱的主題

想象一下,這就像是給你的微信群設置了密碼,并且限制了誰能發言、誰能看到消息。在物聯網世界,這種保護措施不是可選的,而是必須的!

MQTT的高級特性

除了基本功能外,MQTT還有一些高級特性:

  1. 保留消息:服務器會保存標記為"保留"的消息,新訂閱者連接時立即收到
  2. 遺囑消息:客戶端異常斷開時自動發布的消息
  3. 共享訂閱:多個客戶端共享同一個訂閱,實現負載均衡
  4. MQTT 5.0新特性:消息過期、主題別名、用戶屬性等

這些功能讓MQTT變得更加強大和靈活。就像一個初看簡單的瑞士軍刀,打開后卻發現它能完成各種意想不到的任務!

MQTT與其他協議的對比

為什么選擇MQTT而不是其他協議?讓我們做個對比:

特性MQTTHTTPCoAPAMQP
協議模型發布/訂閱請求/響應請求/響應發布/訂閱
消息開銷極小中等
QoS級別0,1,2可靠/不可靠復雜QoS
適用場景低帶寬網頁應用資源受限企業消息

看到這個對比,你會發現MQTT在物聯網場景中的優勢多么明顯!它就像是專為物聯網"量身定制"的通信協議。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/901758.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/901758.shtml
英文地址,請注明出處:http://en.pswp.cn/news/901758.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構——反射、枚舉以及lambda表達式

1. 反射 Java的反射&#xff08;reflection&#xff09;機制是在運?時檢查、訪問和修改類、接?、字段和?法的機制&#xff1b;這種動態獲取信息以及動態調?對象?法的功能稱為java語?的反射&#xff08;reflection&#xff09;機制。 用途 1. 框架開發 2. 注解處理 3.…

C語言教程(十):C 語言函數詳解

一、引言 在 C 語言中&#xff0c;函數是一組執行特定任務的代碼塊。通過將復雜的程序邏輯劃分為多個函數&#xff0c;不僅能提高代碼的可讀性、可維護性&#xff0c;還便于代碼的復用。無論是簡單的數學計算&#xff0c;還是復雜的系統操作&#xff0c;函數都發揮著核心作用。…

力扣面試150題--有效的字母異位詞和字母異位詞分組

Day 24 題目描述 思路 初次思路&#xff1a;如果兩個字符串為異位詞&#xff0c;說明它們長度相同并且字母出現的次數相同&#xff0c;于是有以下做法&#xff1a; 定義一個map&#xff0c;來保存s中每個字符的出現次數處理特殊情況&#xff0c;如果長度不同&#xff0c;直接…

數理邏輯(Mathematical Logic)綜論與跨學科應用

李升偉 整理 數理邏輯&#xff08;Mathematical Logic&#xff09;是現代邏輯學與數學交叉的核心學科&#xff0c;以嚴格的數學方法研究邏輯推理的形式與規律。其發展深刻影響了數學基礎、計算機科學、語言哲學等領域。以下從多個維度綜論數理邏輯&#xff1a; 1. 核心分支 命…

高性能內存kv數據庫Redis(續)

目錄 四.主從同步與對象模型 1.Redis 淘汰策略 2.Redis 如何做到 持久化 2.1 redis為什么要實現持久化 2.2fork進程的寫時復制機制 2.3大Key的影響 2.4redis做持久化的方式 2.5 aof 2.6 rdb 2.7 redis 持久化方式的優缺點 3.redis里面的高可用體現在哪里&#xff1f; 3.1r…

泛型算法——只讀算法(一)

在 C 標準庫中&#xff0c;泛型算法的“只讀算法”指那些 不會改變它們所操作的容器中的元素&#xff0c;僅用于訪問或獲取信息的算法&#xff0c;例如查找、計數、遍歷等操作。 accumulate std::accumulate()是 C 標準庫**numeric**頭文件中提供的算法&#xff0c;用于對序列…

SvelteKit 最新中文文檔教程(21)—— 最佳實踐之圖片

前言 Svelte&#xff0c;一個語法簡潔、入門容易&#xff0c;面向未來的前端框架。 從 Svelte 誕生之初&#xff0c;就備受開發者的喜愛&#xff0c;根據統計&#xff0c;從 2019 年到 2024 年&#xff0c;連續 6 年一直是開發者最感興趣的前端框架 No.1&#xff1a; Svelte …

健康養生:開啟活力生活的密鑰

當我們在健身房看到年逾六旬卻身形矯健的老人&#xff0c;在公園偶遇精神矍鑠、步伐輕快的長者&#xff0c;總會驚嘆于他們的健康狀態。其實&#xff0c;這些都得益于長期堅持科學的養生之道。健康養生并非遙不可及的玄學&#xff0c;而是融入生活細節的智慧。? 在飲食的世界…

Linux信號三部曲:產生機制、處理方式與內核接口

Linux系列 文章目錄 Linux系列前言一、背景知識鋪墊1.1 信號的基本概念1.2 進程對信號的處理 二、信號的產生2.1 前臺進程和后臺進程2.2 鍵盤組合鍵2.3 kill 命令2.4 系統調用2.4.1 signal()接口2.4.2 kill()接口2.4.3 raise()接口2.4.4 abort()接口 總結 前言 Linux中&#x…

win7/win10/macos如何切換DNS,提升網絡穩定性

本篇教程教您如何在Windows10、Windows8.1、Windows7、MacOS操作系統切換DNS&#xff0c;以提升系統的穩定性&#xff0c;獲得更好的操作體驗。 Windows10及Windows8.1 1、右鍵單擊“此計算機”&#xff0c;然后選擇“屬性”。進入Windows系統界面后&#xff0c;選擇左側的“…

移動硬盤突然打不開緊急救援指南:從排查到完整恢復?

突發狀況的典型特征? 當移動硬盤突然打不開時&#xff0c;用戶常會遇到多種異常表現&#xff1a;接入電腦后硬盤指示燈雖亮但無法識別、系統反復提示“設備未連接成功”或彈出“磁盤結構損壞”的警告。部分情況下&#xff0c;資源管理器中的盤符雖可見&#xff0c;但雙擊后顯示…

華為OD機試真題——統計匹配的二元組個數(2025A卷:100分)Java/python/JavaScript/C++/C語言/GO六種最佳實現

2025 A卷 100分 題型 本文涵蓋詳細的問題分析、解題思路、代碼實現、代碼詳解、測試用例以及綜合分析&#xff1b; 并提供Java、python、JavaScript、C、C語言、GO六種語言的最佳實現方式&#xff01; 2025華為OD真題目錄全流程解析/備考攻略/經驗分享 華為OD機試真題《統計匹配…

半導體制造如何數字化轉型

半導體制造的數字化轉型正通過技術融合與流程重構&#xff0c;推動著這個精密產業的全面革新。全球芯片短缺與工藝復雜度指數級增長的雙重壓力下&#xff0c;頭部企業已構建起四大轉型支柱&#xff1a; 1. 數據中樞重構產線生態 臺積電的「智慧工廠4.0」部署著30萬物聯網傳感器…

[Spark]深入解密Spark SQL源碼:Catalyst框架如何優雅地解析你的SQL

本文內容組織形式 總結具體例子執行語句解析層優化層物理計劃層執行層 猜你喜歡PS 總結 先寫個總結&#xff0c;接下來會分別產出各個部分的源碼解析&#xff0c;Spark SQL主要分為以下五個執行部分。 具體例子 接下來舉個具體的例子來說明 執行語句 SELECT name, age FR…

【數據結構】4.單鏈表實現通訊錄

在上一篇文章我們學會了用單鏈表來實現各種方法&#xff0c;在這一篇文章我們將在單鏈表的基礎上實現通訊錄。 0、準備工作 實現通訊錄之前&#xff0c;我們還需要在單鏈表的基礎上添加2個文件&#xff0c;頭文件Contact.h和源文件Contact.c。Contact.c來實現通訊錄方法的聲明…

【bash】.bashrc

查看當前路徑文件數量 alias file_num"ls -l | grep ^- | wc -l"查看文件大小 alias file_size"du -sh"alias ll alias ll"ls -ltrh"cd的同時執行ll alias cdcdls; function cdls() {builtin cd "$1" && ll }自定義prompt…

微信小程序實戰案例 - 餐館點餐系統 階段 2 – 購物車

階段?2 – 購物車&#xff08;超詳細版&#xff09; 目標 把“加入購物車”做成 全局狀態&#xff0c;任何頁面都能讀寫在本地 持久化&#xff08;關閉小程序后購物車仍在&#xff09;新建 購物車頁&#xff1a;數量增減、總價實時計算、去結算入口打 Git?Tag v2.0?cart 1. …

從紅黑樹到哈希表:原理對比與典型場景應用解析(分布式以及布隆過濾器)

在數據結構的世界里&#xff0c;紅黑樹一直以「自平衡二叉查找樹」的身份備受贊譽。憑借紅黑節點的精妙設計&#xff0c;它能將插入、刪除、查找的時間復雜度穩定控制在 ( log ? n ) (\log n) (logn)&#xff0c;成為處理有序數據的經典方案。然而&#xff0c;當業務場景對「…

游戲報錯?MFC140.dll怎么安裝才能解決問題?提供多種MFC140.dll丟失修復方案

MFC140.dll 是 Microsoft Visual C 2015 運行庫的重要組成部分&#xff0c;許多軟件和游戲依賴它才能正常運行。如果你的電腦提示 "MFC140.dll 丟失" 或 "MFC140.dll 未找到"&#xff0c;說明系統缺少該文件&#xff0c;導致程序無法啟動。本文將詳細介紹 …

《電子類專業:通往科技未來的鑰匙》

一、電子類專業全景概覽 在當今科技飛速發展的時代,電子類專業無疑占據著現代科技體系中基礎與核心的重要地位。從我們日常生活中不可或缺的智能手機、電腦,到推動社會進步的人工智能、大數據技術,再到探索宇宙奧秘的航天航空設備,電子類專業的身影無處不在。它就像一把萬…