MQTT Temelleri

MQTT Paket Yapısı: Sabit Başlık, Değişken Başlık ve Payload

MQTT paketlerinin bayt düzeyinde incelemesi: sabit başlığın tür ve bayrakları nasıl kodladığı, remaining length'in nasıl çalıştığı ve değişken başlık ile payload'ın neler içerdiği; Wireshark ile yakalayabileceğiniz bir CONNECT ve PUBLISH üzerinden.

MQTT paket yapısını açıklamak için sabit başlık, değişken başlık ve payload olarak bölünmüş bir MQTT PUBLISH hex dökümü
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

MQTT paket yapısı bilinçli olarak kompakttır: her paket en az iki baytlık bir sabit başlıkla başlar, ardından isteğe bağlı bir değişken başlık ve isteğe bağlı bir payload gelir. Bu inceleme gerçek CONNECT, CONNACK ve PUBLISH paketlerini bayt bayt çözümler; böylece bir Wireshark yakalamasını veya hex dökümünü güvenle okuyabilir ve kendi client'larınızdaki kodlama hatalarını fark edebilirsiniz.

Her MQTT Paketinin Üç Bölümü

Her MQTT kontrol paketi aynı düzeni izler:

Bölüm Bulunduğu paketler İçerik
Sabit başlık Tüm paketler Paket türü, bayraklar, remaining length
Değişken başlık Çoğu paket Topic adı, paket tanımlayıcısı, protokol adı gibi pakete özgü alanlar ve MQTT 5'te property'ler
Payload Bazı paketler CONNECT'te client ID ve kimlik bilgileri, PUBLISH'te uygulama mesajı, SUBSCRIBE'da topic filtreleri

En küçük paketler olan PINGREQ, PINGRESP ve MQTT 3.1.1 DISCONNECT yalnızca iki baytlık sabit başlıktan oluşur. Bu tasarruf, MQTT'nin yavaş bağlantılarda iyi çalışmasının önemli bir nedenidir ve MQTT bant genişliği kullanımını tahmin ederken yapıyı anlamanın neden işe yaradığını da açıklar.

Sabit Başlık

İlk bayt iki yarıya ayrılır:

Bit:     7  6  5  4 | 3  2  1  0
         packet type | flags

Üst dört bit, 1 (CONNECT) ile 15 (AUTH) arasında paket türünü tutar. Alt dört bit bayraklardır. Çoğu pakette bayraklar sabit, ayrılmış değerlerdir; yalnızca PUBLISH bunları anlamlı şekilde kullanır:

Bit PUBLISH'teki anlamı
3 DUP: bu bir QoS 1 veya 2 mesajının yeniden teslimidir
2-1 QoS seviyesi: 00, 01 veya 10
0 RETAIN: broker bu mesajı saklamalıdır

Yani 0x30 ilk baytı bir QoS 0 PUBLISH, 0x32 QoS 1, 0x31 retained bir QoS 0 mesajı ve 0x3A ise DUP ayarlı bir QoS 1 yeniden teslimidir. SUBSCRIBE, UNSUBSCRIBE ve PUBREL'in bayrakları 0010 olmak zorundadır; bu yüzden 0x82, 0xA2 ve 0x62 olarak görünürler. MQTT kontrol paketleri referansı her türü ilk baytıyla birlikte listeler.

Remaining Length Kodlaması

İlk bayttan sonra remaining length gelir: sabit başlığın kendisi hariç, değişken başlık ile payload'daki bayt sayısı. Bir ile dört bayt arasında değişen bir variable byte integer kullanır. Her bayt yedi bitlik değer taşır ve en üst bit "ardından başka bir bayt geliyor" anlamına gelir.

Değer aralığı Kullanılan bayt
0 ile 127 1
128 ile 16.383 2
16.384 ile 2.097.151 3
2.097.152 ile 268.435.455 4

Örnek: 321 değerinde bir remaining length. 321 = 2 x 128 + 65 olduğundan ilk bayt devam biti ayarlı 65'tir (0xC1) ve ikinci bayt 2'dir (0x02). Protokolün sıkça alıntılanan 256 MB paket tavanı bu dört baytlık maksimumdan gelir; MQTT mesaj boyutu sınırı rehberi gerçek broker'ların neden çok daha düşük sınırlar belirlediğini açıklar.

Hex dökümlerini okurken kullanabileceğiniz bir çözücü:

def decode_remaining_length(data: bytes, offset: int = 1):
    multiplier, value = 1, 0
    for i in range(4):
        byte = data[offset + i]
        value += (byte & 0x7F) * multiplier
        if byte & 0x80 == 0:
            return value, i + 1  # değer, kullanılan bayt sayısı
        multiplier *= 128
    raise ValueError("Malformed remaining length")

print(decode_remaining_length(bytes([0x30, 0xC1, 0x02])))  # (321, 2)

Gerçek Bir Oturumu Adım Adım İncelemek

mosquitto_pub'ın varsayılan olarak kullandığı MQTT 3.1.1 ile herkese açık MQTT test broker'ına tek bir mesaj publish etmek için şu komutu çalıştırın:

mosquitto_pub -h broker.connectmq.com -p 1883 -i demo-a1b2 \
  -t "connectmq/demo/a1b2/t" -m "21.5" -d

1883 portu şifresizdir; bu yüzden bir paket yakalaması her baytı gösterir. Wireshark'ta ağ arayüzünüzde yakalama yapın ve mqtt görüntüleme filtresini uygulayın. Wireshark 1883 portunu otomatik olarak MQTT olarak çözümler; CONNECT, CONNACK, PUBLISH ve DISCONNECT'i görürsünüz. Kendi rastgele topic segmentinizi kullanın ve herkese açık broker'daki her şeyin başkaları tarafından okunabileceğini unutmayın.

CONNECT

Client'ın ilk paketi 23 bayttır:

10 15                         Sabit başlık: tür 1 (CONNECT), remaining length 21
00 04 4D 51 54 54             Protokol adı: uzunluk 4, "MQTT"
04                            Protokol seviyesi: 4 = MQTT 3.1.1
02                            Connect bayrakları: Clean Session
00 3C                         Keep alive: 60 saniye
00 09 64 65 6D 6F 2D 61 31 62 32   Payload: client ID uzunluğu 9, "demo-a1b2"

Connect bayrakları baytı daha yakından bakmayı hak ediyor. Bit 1 Clean Session, bit 2 Will Flag, bit 3-4 Will QoS, bit 5 Will Retain, bit 6 Password Flag ve bit 7 User Name Flag'dir. Kullanıcı adı, parola ve clean session ile bağlanan bir client 0xC2 gönderir. Bu bayraklar ayarlıysa kullanıcı adı ve parola, her biri iki baytlık bir uzunluk önekiyle payload'da client ID'nin ardından gelir. Gerçek kimlik bilgileriyle her zaman 8883 portunda TLS kullanmanın bir nedeni budur: 1883 portunda düz metin olarak iletilirler.

CONNACK

Broker dört baytla yanıt verir:

20 02 00 00

Tür 2, remaining length 2, Session Present 0, dönüş kodu 0 (kabul edildi). Son bayt başka herhangi bir değerse bu bir rettir; MQTT CONNACK dönüş kodları rehberi her değeri çözümler.

PUBLISH

Mesajın kendisi 29 bayttır:

30 1B                         Sabit başlık: PUBLISH, QoS 0, retain yok; remaining length 27
00 15                         Topic uzunluğu: 21
63 6F 6E 6E 65 63 74 6D 71 2F 64 65 6D 6F 2F 61 31 62 32 2F 74
                              Topic: "connectmq/demo/a1b2/t"
32 31 2E 35                   Payload: "21.5"

Neyin eksik olduğuna dikkat edin: paket tanımlayıcısı yoktur, çünkü QoS 0 mesajları asla onaylanmaz. -q 1 ile ilk bayt 0x32 olur, topic'ten sonra iki baytlık paket tanımlayıcısı görünür ve broker dört baytlık bir PUBACK ile (40 02 artı tanımlayıcı) yanıt verir. Bir payload uzunluk alanı da yoktur; payload, remaining length'e göre değişken başlıktan sonra kalan her şeydir.

DISCONNECT

Son olarak client E0 00 gönderir: tür 14, remaining length 0. MQTT 3.1.1'de paketin tamamı budur.

MQTT 5'te Neler Değişir?

MQTT 5 aynı iskeleti korur ancak çoğu paketin değişken başlığına property'ler ekler. Bir property bölümü kendi variable byte integer uzunluğuyla başlar ve ardından tanımlayıcı-değer çiftleri gelir. Hiç property olmasa bile 00 uzunluk baytı bulunur.

Aynı oturum MQTT 5 üzerinden yapıldığında:

  • CONNECT'in protokol seviyesi 05 olur ve keep alive'dan sonra bir property uzunluğu gelir.
  • CONNACK bir reason code ve property'leri içerecek şekilde büyür ve genellikle Maximum Packet Size, Topic Alias Maximum veya Maximum QoS gibi sınırları bildirir.
  • PUBLISH'te topic'ten (ve paket tanımlayıcısından) sonra bir property uzunluğu bulunur; bu yüzden property'siz bir QoS 0 publish bir bayt daha büyüktür.
  • DISCONNECT bir reason code ve property'ler taşıyabilir; broker bir bağlantıyı neden kapattığını bu şekilde açıklar.

Topic Alias, Message Expiry Interval ve User Properties gibi property'ler, MQTT 5 özelliklerinin çoğunu mümkün kılan şeydir.

Yaygın Kodlama Hataları ve Nasıl Fark Edilirler

Özel bir client yazıyorsanız veya bir gateway'de MQTT ayrıştırıyorsanız önce bunları kontrol edin:

  1. Remaining length'in sabit iki baytlık bir alan olarak yazılması. Küçük paketlerde çalışır, 127 baytın üzerinde bozulur.
  2. String uzunluklarının bayt yerine karakter olarak sayılması. ASCII olmayan topic adlarında karakterden çok bayt bulunur ve hatalı paketler üretilir.
  3. QoS 1 veya 2'de eksik paket tanımlayıcısı. Broker payload'ınızın bir kısmını tanımlayıcı olarak okur ve topic düzgün görünür; bu yüzden hata bozuk veri gibi görünür.
  4. SUBSCRIBE veya PUBREL'de yanlış ayrılmış bayraklar. Broker'lar bunları hatalı paket olarak ele almak ve bağlantıyı kapatmak zorundadır.
  5. Bir client'ı MQTT 5'e geçirirken boş property uzunluğunu unutmak.

Wireshark hatalı paketleri açıkça işaretler ve bir MQTT 5 broker DISCONNECT'te 0x81 Malformed Packet reason code'uyla yanıt verir; bu, sessiz bir kapatmadan çok daha hızlı teşhis edilir. Yetkili tanımlar için OASIS MQTT spesifikasyonuna bakın.

Paketleri Gerçek Bir ConnectMQ Broker'ına Karşı İnceleyin

Paketleri okumak MQTT'yi anlamanın en hızlı yoludur; MQTT eğitimi bu temelin üzerine oturumlar, QoS ve retained mesajlarla inşa eder. ConnectMQ, tam da bu tür deneyler için broker.connectmq.com adresindeki herkese açık broker'ı, gerçek veriler devreye girdiğinde ise TLS 8883 portunda özel broker'ları çalıştırır.

ConnectMQ ile Paket Yakalamalarından Üretime Geçin

Client'ınız hazır olduğunda, yönetilen bir MQTT broker size şifreli uç noktalar, verilmiş kimlik bilgileri ve tarayıcı içi istemci ile canlı topic gezgini olan bir portal sunar. app.connectmq.com adresinde, kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun veya bulut MQTT broker seçimi hakkında daha fazlasını okuyun.

Sık Sorulan Sorular

En küçük MQTT paketi ne kadar büyüktür?

İki bayt. PINGREQ, PINGRESP ve MQTT 3.1.1 DISCONNECT yalnızca sabit başlıktan oluşur: tür ve bayraklar için bir bayt ve sıfıra ayarlanmış bir baytlık remaining length.

Remaining length neleri içerir?

Değişken başlığın ve payload'ın baytlarını sayar, ancak sabit başlığın kendisini saymaz. Bir ile dört bayt arasında bir variable byte integer olarak kodlanır.

Parolamı neden Wireshark'ta okuyabiliyorum?

Çünkü 1883 portu şifresizdir ve CONNECT, kullanıcı adını ve parolayı payload'ında taşır. Gerçek kimlik bilgileri için 8883 portunda TLS veya 8084 portunda güvenli WebSocket kullanın.

PUBLISH paketi payload uzunluğunu içerir mi?

Hayır. Payload uzunluğu örtüktür: remaining length'ten değişken başlığın boyutunun çıkarılmasıyla bulunur; değişken başlık topic adını, QoS 1 ve 2 için paket tanımlayıcısını ve MQTT 5'te property'leri içerir.

İlgili yazılar

MQTT'yi Kim İcat Etti? Petrol Boru Hatlarından IoT'ye Uzanan Tarih

MQTT, 1999'da IBM'den Andy Stanford-Clark ve Arcom'dan Arlen Nipper tarafından petrol boru hatlarını uydu üzerinden izlemek için icat edildi. Açık kaynağa, OASIS'e, ISO'ya ve bugünün yönetilen bulut broker'larına uzanan yolculuğunu izleyin.

7 dk okuma

MQTT Maksimum Mesaj Boyutu: Sınırlar ve Büyük Payload Stratejileri

MQTT teknik olarak 256 MB'lık bir paket taşıyabilir, ancak broker'lar, istemci kütüphaneleri ve cihazlar çok daha düşük sınırlar uygular. Gerçek sınırların nerede olduğunu, aşıldıklarında ne olduğunu ve büyük payload'ların nasıl gönderileceğini öğrenin.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.