MQTT比TCP協議好在哪兒?

希望詳細點,不只是百度就能搜到的資料。


MQTT是非常流行的設備的接入協議,包括IBM、亞馬遜、微軟的IoT託管服務都有支持。MQTT基於TCP,實現了非同步Pub/Sub,好比發個微信,無需等待對方確認便可以繼續,以及為物聯網提供了許多體貼的設計,比如QoS,比如「遺言」的設計。

篇幅有限,無法完全枚舉MQTT的優越性,建議參考以下文章:

  1. MQTT入門篇
  2. MQTT進階篇
  3. MQTT安全篇
  4. MQTT實戰篇

總之,物聯網項目應該使用MQTT這個TCP的「子類」才靠譜。


TCP是面向鏈接的可靠的傳輸層的通信協議,包括三次握手和四次揮手~

而MQTT是發布/訂閱協議(publish/subscribe),採用C/S模式,輕量級,適用於物聯網,同時MQTT協議中的用戶是通過TCP協議接入伺服器(代理,broker)的~

就像這個圖,client A發布話題temperature,如果clientB 和C訂閱了temperature話題,就會受到client A發布的消息~
此外,為了保障通信安全,MQTT也會採用SSL/TLS。Facebook好像採用了MQTT~MQTT和CoAP是物聯網目前最具前景的兩個協議。


不是一個層級的。MQTT是基於TCP協議的應用層協議。


MQTT 協議是建立在 TCP 協議之上的,

就好比汽車地盤上有四個輪胎就能跑了,但是想要大家開車更舒服,我們還是得給底盤加個殼。

為什麼要在 TCP 協議之上再封裝一層 MQTT 協議呢?

舉個例子,如果你要用 TCP 協議做一個即時聊天室,那麼你:

  1. 首先寫一個伺服器程序,監聽某個埠,這樣客戶端就能連接上來了。然後大家就能向你的伺服器發送數據了。
  2. 但是你不希望隨便誰都能連接你的伺服器並且往你的伺服器里發東西,於是你寫了一個註冊頁面,讓別人先去註冊賬號,然後他們在客戶端創建連接時發送的第一個TCP報文必須包含了賬號密碼。這樣當你收到第一個報文之後,你就能判斷這個連接是否合法了。
  3. 但是發過來的賬號密碼,具體擺在報文什麼位置,也得事先約定好吧,不然怎麼知道哪幾位是賬號哪幾位是密碼,於是你要求:第一個位元組為1,用來告訴你這是一個請求連接的報文。然後第二個位元組是報文剩下的長度(這個沒啥異議,粘包處理必備),然後是「餅乾熊最帥」這樣一個固定的字元串(沒啥意思,就是開心),後面緊跟著就是賬號,然後是密碼。但是賬號有多長呢,所以賬號第一個位元組是賬號的長度,剩下才是賬號內容,這樣就解決了「賬號有多長」的問題了,密碼同理。
  4. 如果賬號密碼不匹配就斷開連接並且返回一句「xxxx off」,如果創建連接後半天不發送任何東西也斷開連接。
  5. 現在大家的客戶端都連接上來了,你在伺服器保存了一個`賬號:socket`的map,能通過任何一個賬號找到這個人的socket並向他發送信息。接下來大家要開始聊天了。
  6. 在聊天室中,一個人發送的消息其他人都能收到,所以你添加了聊天室的概念,用戶首先去你的web頁面創建聊天室,然後會得到一個聊天室的ID。然後用戶要加入聊天室,必須先發送一個加入聊天室的報文。然後你要求報文第一個位元組為2代表加入聊天室的請求報文,然後是報文剩餘長度,然後是聊天室ID,聊天室ID有多長?我們還是用第一個位元組代表長度,剩下的內容為具體ID的形式來搞定。
  7. 現在有多個用戶加入了聊天室,其中每個用戶又都加入了多個聊天室。假設現在大家在聊天室A中開始聊天。用戶甲向伺服器發送消息,然後你發現你不知道這條消息是請求連接還是要加入聊天室還是幹啥,所以發送消息也應該定義一種報文類型。於是你要求發送消息的報文的第一個位元組為3,那麼這個報文是發送到哪個聊天室的呢?於是你要求報文後面跟上聊天室ID,最後是具體的消息內容。
  8. 伺服器收到第一個位元組為3的消息,就知道這是一個聊天消息。然後根據上面帶的聊天室ID以及你在伺服器存儲的用戶和聊天室的關係,找到了這個聊天室里的所有人,然後你就把消息發給這裡面的所有人了。

上面這個例子,在連接伺服器(檢查合法性、斷開連接)、訂閱主題(加入聊天室)、發布消息這些過程中,你約定的報文格式和設計的伺服器處理邏輯就是 MQTT 協議的內容,當然我舉的例子非常粗糙

真正的MQTT協議要求的處理邏輯和報文格式都完善很多,但是協議本身還是很簡單的,具體內容去看 MQTT 的文檔吧。

MQTT英文文檔:MQTT Version 3.1.1

MQTT文檔中文翻譯:Introduction · MQTT協議中文版


MQTT是在TCP和應用層之間加了一層,實現非同步按主題訂閱/發布消息,實現了生產者與消費者的脫耦。

其思想源於IBM的MQ,MQTT編碼方式採用UTF-8,編碼更高效,很適用於物聯網應用,也可用於即時聊天應用。

**MQTT就是觀察者模式的網路放大版。**

有很多MQTT伺服器,包括開源的,可以安裝於不同平台。mosquitto蚊子就是很有名的一個開源伺服器。

用戶可以很容易地,用不同的語言來開發客戶端程序,c/c++,java,python,micopython...,以至於javascript嵌入到網頁中等。也可以在命令行中測試。

當前本人(hyper)在esp8266(micropython,MQTT客戶端),esp8266(Micropython,MQTT客戶端),Raspberry pi3(Debian,MQTT伺服器,mosquitto)調試成功。


mqyy基於tcp,沒有好壞差別


推薦閱讀:

思科模擬器如何配置兩個不同的vlan通過一個路由器ping通另一個網段的電腦?
網路上有若干客戶端向一台機器的某個埠一直不停發送UDP包 這台機器打開埠和不打開埠的區別在哪?
《TCP/IP詳解 卷1:協議》哪些章節需要重點閱讀?
OpenWrt 路由器如何讓 lan 口主機獲得 ipv6 網路訪問?

TAG:物聯網 | 計算機網路 | TCPIP | MQTT |