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
05olur 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:
- Remaining length'in sabit iki baytlık bir alan olarak yazılması. Küçük paketlerde çalışır, 127 baytın üzerinde bozulur.
- String uzunluklarının bayt yerine karakter olarak sayılması. ASCII olmayan topic adlarında karakterden çok bayt bulunur ve hatalı paketler üretilir.
- 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.
- SUBSCRIBE veya PUBREL'de yanlış ayrılmış bayraklar. Broker'lar bunları hatalı paket olarak ele almak ve bağlantıyı kapatmak zorundadır.
- 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.



