✅ مقدمه:
پروتکل MQTT (Message Queuing Telemetry Transport) یکی از محبوبترین پروتکلهای ارتباطی در حوزه اینترنت اشیاء (IoT) است که با طراحی سبک و کارآمد خود، امکان انتقال پیامها را با حداقل مصرف پهنای باند و انرژی فراهم میسازد. در این مقاله به بررسی کامل ساختار پکتها، مراحل ارتباط بین کلاینت و سرور، فرمت پیامها و استانداردهای رمزگذاری در MQTT میپردازیم.
🟢 ساختار کلی ارتباط در MQTT
-
دو مسیر ارتباطی اصلی: از کلاینت به سرور و بالعکس
-
نقش کلیدی پکتهای CONNECT و CONNACK
-
توضیح کامل فیلدهای موجود در CONNECT (ClientId، CleanSession، LastWill و…)
🟢 ساختار پاسخ سرور (CONNACK)
-
معنی فیلد SessionPresent در شرایط مختلف
-
جدول کامل Return Codeها با توضیحات معنایی
🟢 استاندارد رمزگذاری دادهها با UTF-8
-
توضیح String Length MSB/LSB
-
مثال کامل رمزگذاری رشته “A” با فرمت UTF-8
🟢 ساختار پکت کنترلی MQTT
-
اجزای اصلی هر پکت: Fixed Header، Variable Header، Payload
-
انواع پکتهای کنترلی (CONNECT, PUBLISH, SUBSCRIBE, …)
-
جدول کامل انواع پکتها و جهت جریان ارتباطی آنها
🟢 ساختار Fixed Header و بیتهای پرچم
-
تشریح بیتهای 0 تا 7 در Byte اول هدر
-
پرچمهای خاص برای هر نوع پکت
-
جدول مقایسه پرچمها در پکتهای مختلف
🟢 Remaining Length و نحوه رمزگذاری آن
-
مفهوم Remaining Length
-
نحوه رمزگذاری مقادیر چندبایتی
-
جدول محدوده مقادیر با تعداد بایتها
🟢 هدر متغیر (Variable Header)
-
شناسه پکتها و انواع پکتهایی که به آن نیاز دارند
-
فرمت دقیق Packet Identifier (MSB و LSB)
🟢 Payload در پکتهای کنترلی
-
معرفی پکتهایی که دارای Payload هستند
-
جدول بررسی نیاز به Payload برای انواع پکتها
در پروتکل و ساختار MQTT به طور كلي دو جريان داده براي پكت¬هاي كنترلي وجود دارد:
- پکتهای ارسالی از کلاینت به سرور
- پکتهای ارسالی از سرور به کلاینت
1- پکت ارسالی از کلاینت به سرور

به پکتهای ارسالی از سمت کلاینت به سرور برای ارتباط و ارسال اطلاعات، CONNECT گفته میشود .یک پکتCONNECT که از کلاینت به سمت سرور میرود شامل اطلاعات نمايش داده شده در شکل زیر است.
- ClientId:هر کلاینت دارای یک Id است که در این بخش نشان داده میشود.
- CleanSession:اگر مقدار CleanSession برابر False باشد سرور دادهها را کش کرده و اگر کلاینتی دوباره متصل شود اطلاعات قدیمی و کش شده را دریافت خواهد کرد.
- Username: نام کاربری هر کلاینت است که برای Login استفاده میشود.
- Password:رمز هر کلاینت که برای Login استفاده میشود.
- LastWillTopic: عنوانی است که کلاینت اطلاعات خود را بر روی آن قرار داده است. کلاینت از آن برای نمایش اطلاعات استفاده میکند.
- LastWillQoS:این پارامتر مقدار QoS را نشان میدهد.
- LastWillMassage:این پیام در صورت قطع اتصال کلاینت با سرور و قطع WillTopic به صورت اتفاقی و غیره منتظره ارسال میشود.
- LastWillRetain:زمانی که برابر با False باشد WillMasasge كش نمیشود، اگر هم برابر True باشد این پیام كش میشود.
- KeepAlive:مقدار مدت زمانی است که کلاینت و سرور میتوانند بدون ارسال هیچ پیامی ارتباط خود را ذخيره کنند.
2- پکتهای ارسالی از سرور به کلاینت
به پکتهای ارسالی از سمت سرور به کلاینت پکت CONNACK گفته میشود. شکل زیر هم جوابی است که سرور به کلاینت ارسال میکند.

- SessionPresent:مقدار آن نشان دهنده این است که آیا سرور قبلا با کلاینت ارتباط داشته یا نه.
اگر کلاینت به سرور با استفاده از CleanSession که بر روی True تنظیم شده است وصل شود مقدار SessionPresent همیشه False است. زیرا CleanSession کل اطلاعات اتصال فعلی را از بین خواهد برد. اما اگر کلاینت با استفاده از CleanSession که مقدار آن برابر False است با سرور ارتباط برقرار کند، در این صورت دو حالت به وجود میآید. حالت اول به این صورت است که اگر اطلاعاتی از نشست برای آن ClientId موجود باشد مقدار SessionPresent برابر با True خواهد شد. اما حالت دوم به این صورت است که سرور هیچ اطلاعاتی از این ClientId ندارد، در آن صورت این مقدار False خواهد بود.
این حالت نشان میدهد آیا کلاینت نیاز به عضویت در مباحث و تاپیکهای جدید دارد یا خیر و یا بداند آیا هنوز موضوعات در یک نشست ذخیره میشوند یا نمیشوند.
- Ruturn Code:این مقدار نشان میدهد که آیا اتصال بین سرور و کلاینت موفقیت آمیز بوده یا خیر، که خود دارای مقادیر مختلف است. جدول زیر نشان دهنده این است که هر عدد چه جوابی را نشان میدهد.
| Return code response | Return code |
| اتصال برقرار شد. | 0 |
| اتصال رد شد، نسخه پروتکل غیر قابل قبول است. | 1 |
| اتصال رد شد، شناسه اشتباه است. | 2 |
| اتصال رد شد، سرور در دسترس نیست. | 3 |
| اتصال رد شد، نام کاربری یا رمز عبور اشتباه است. | 4 |
| اتصال رد شد، مجاز نیست. | 5 |
نمایش داده ها
هر بايت داراي 8 بيت است كه به ترتيب از 0 تا 7 برچسب گذاري ميشوند. اعداد صحيح 16 بيتي هستند كه از دوبايت شامل بايت كمارزش (LSB) و بايت پرارزش (MSB) تشكيل شده است.
استاندارد نامگذاري براساس UTF-8 است که رمزگذاری کاراکترهای ASCII را برای پشتیبانی از ارتباطات مبتنی بر متن بهینه میکند.
هر یک از این رشتهها یک فیلد دو بایتی ابتدايي دارد که تعداد بایتهای خود رشته رمزگذاری شده UTF-8 را نشان میدهد، در جدول زیر ساختار رشتههای رمزگذاری شده UTF-8 نشان داده شده است. تمام رشتههای رمزگذاری شده UTF-8 میتوانند هر طولی در محدوده 0 تا 65535 بایت داشته باشند.
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| byte 1 | String length MSB | |||||||
| byte 2 | String length LSB | |||||||
| byte 3 …. | UTF-8 Encoded Character Data, if length > 0. | |||||||
مثال: به عنوان مثال براي ارسال كاراكتر “A” با فرمت String به صورت جدول زیر عمل شود.
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| byte 1 | String Length MSB (0x00) | |||||||
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
| byte 2 | String Length LSB (0x05) | |||||||
| 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | |
| byte 3 | ‘A’ (0x41) | |||||||
| 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | |
| byte 4 | (0xF0) | |||||||
| 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | |
| byte 5 | (0xAA) | |||||||
| 1 | 0 | 1 | 0 | 1 | 0 | 1 | 0 | |
| byte 6 | (0x9B) | |||||||
| 1 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | |
| byte 7 | (0x94) | |||||||
| 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | |
فرمت پكت کنترلی MQTT
پروتکل MQTT با تبادل یک سری پكتهای کنترلی با روشی از پيش تعریف شده کار میکند. این بخش فرمت این پكت ها را توضیح میدهد.
یک پكت کنترلی MQTT حداکثر از سه قسمت تشکیل شده است، همیشه به ترتیب نشان داده شده در جدول زیر عمل ميشود.
| Fixed header, present in all MQTT Control Packets |
| Variable header, present in some MQTT Control Packets |
| Payload, present in some MQTT Control Packets |
-
2- هدر ثابت
هر پكت کنترلی MQTT حاوی یک هدرثابت است. جدول زیر فرمت هدرثابت را نشان میدهد.
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| byte 1 | MQTT Control Packet type | Flags specific to each MQTT Control Packet type | ||||||
| byte 2… | Remaining Length | |||||||
چهار بيت پر ارزش (4-7) از بایت 1 به نوع پکت كنترلي در پروتكل اختصاص دارد. در جدول زیر انواع پکتهای کنترلی با مقادیر 4 بیتی فهرست شدهاند.
| Name | Value | Direction of flow | Description | |
| Reserved | 0 | Forbidden | Reserved | |
| CONNECT | 1 | Client to Server | Client request to connect to Server | |
| CONNACK | 2 | Server to Client | Connect acknowledgment | |
| PUBLISH | 3 | Client to Server
or Server to Client |
Publish message | |
| PUBACK | 4 | Client to Server
or Server to Client |
Publish acknowledgment | |
| PUBREC | 5 | Client to Server
or Server to Client |
Publish received (assured delivery part 1) | |
| PUBREL | 6 | Client to Server
or Server to Client |
Publish release (assured delivery part 2) | |
| PUBCOMP | 7 | Client to Server
or Server to Client |
Publish complete (assured delivery part 3) | |
| SUBSCRIBE | 8 | Client to Server | Client subscribe request | |
| SUBACK | 9 | Server to Client | Subscribe acknowledgment | |
| UNSUBSCRIBE | 10 | Client to Server | Unsubscribe request | |
| UNSUBACK | 11 | Server to Client | Unsubscribe acknowledgment | |
| PINGREQ | 12 | Client to Server | PING request | |
| PINGRESP | 13 | Server to Client | PING response | |
| DISCONNECT | 14 | Client to Server | Client is disconnecting | |
| Reserved | 15 | Forbidden | Reserved | |
بیتهای باقیمانده [0-3] از بایت 1 در هدر ثابت حاوی پرچمهاي خاص برای انوع پكت کنترلی MQTT هستند که در جدول زیر اين بیتهای پرچم فهرست شدهاند. برخي از بیتهای پرچم، برای استفادههاي آتي رزرو شده است و گيرنده باید روی مقادير فهرست شده در جدول زیر تنظیم شود. در صورت دریافت پرچمهای نامعتبر، گیرنده باید اتصال شبکه را قطع كند.
| Control Packet | Fixed header flags | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
| CONNECT | Reserved | 0 | 0 | 0 | 0 |
| CONNACK | Reserved | 0 | 0 | 0 | 0 |
| PUBLISH | Used in MQTT 3.1.1 | DUP | QoS | QoS | RETAIN |
| PUBACK | Reserved | 0 | 0 | 0 | 0 |
| PUBREC | Reserved | 0 | 0 | 0 | 0 |
| PUBREL | Reserved | 0 | 0 | 1 | 0 |
| PUBCOMP | Reserved | 0 | 0 | 0 | 0 |
| SUBSCRIBE | Reserved | 0 | 0 | 1 | 0 |
| SUBACK | Reserved | 0 | 0 | 0 | 0 |
| UNSUBSCRIBE | Reserved | 0 | 0 | 1 | 0 |
| UNSUBACK | Reserved | 0 | 0 | 0 | 0 |
| PINGREQ | Reserved | 0 | 0 | 0 | 0 |
| PINGRESP | Reserved | 0 | 0 | 0 | 0 |
| DISCONNECT | Reserved | 0 | 0 | 0 | 0 |
تعداد RemainingLength كه از بایت 2 شروع می شود و در پكت قرار دارد كه شامل هدرمتغيير و Payload نيز ميشود. RemainingLength با استفاده از یک روش رمزگذاری با طول متغیر که مي تواند از 1 تا 127 بايت باشد، کدگذاری میشود. هفت بیت کمارزش هر بایت داده را رمزگذاری میکند و با ارزشترين بیت، اين بايت نشان دهنده وجود بایتهای بعدي است. بنابراین هر بایت 128 مقدار و یک “بیت ادامه” را رمزگذاری میکند. حداکثر تعداد بایت در قسمت RemainingLength چهار بایت است.
مثال: به عنوان مثال، عدد 64 به صورت یک بایت و به فرمت هگزادسيمال کدگذاری میشود و عدد 321 (= 65 + 2*128) به صورت دو بایت کدگذاری میشود که بايت اول کمترین ارزش را دارد. بایت اول 65+128 = 193 است. توجه شود که بیت آخر بايت، حداقل یک بایت بعدی را نشان می دهد. مقدار بایت دوم 2 خواهد بود. جدول زیر مقادیر RemainingLength را نشان میدهد که متناسب با افزایش تعداد بایتها نشان داده شده است.
| Digits | From | To |
| 1 | 0 (0x00) | 127 (0x7F) |
| 2 | 128 (0x80, 0x01) | 16 383 (0xFF, 0x7F) |
| 3 | 16 384 (0x80, 0x80, 0x01) | 2 097 151 (0xFF, 0xFF, 0x7F) |
| 4 | 2 097 152 (0x80, 0x80, 0x80, 0x01) | 268 5 455 (0xFF, 0xFF, 0xFF, 0x7F) |
برخی از انواع پکتهای کنترلی MQTT حاوی یک جزء هدرمتغيير هستند كه بین هدرثابت و Payload قرار ميگيرد. محتوای هدرمتغيير متناسب با نوع پكت متفاوت است. فیلد شناسه پكت و هدرمتغيير در چند نوع از پكتهاي كنترلي رایج است.
به جزء هدر متغیر بسیاری از انواع بسته کنترلی شامل یک فیلد شناسه پكت دو بایتی هستند. این پكتهای کنترلی عبارتند از: PUBLISH ,PUBACK, PUBREC, PUBREL, PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK. در جدول زیر فرمت بايت شناسه پكت نشان داده شده است.
| Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
| byte 1 | Packet Identifier MSB | |||||||
| byte 2 | Packet Identifier LSB | |||||||
پكتهای کنترلی که به شناسه پكت نیاز دارند در جدول زیر نشان داده شده است.
| Control Packet | Packet Identifier field |
| CONNECT | NO |
| CONNACK | NO |
| PUBLISH | YES (If QoS > 0) |
| PUBACK | YES |
| PUBREC | YES |
| PUBREL | YES |
| PUBCOMP | YES |
| SUBSCRIBE | YES |
| SUBACK | YES |
| UNSUBSCRIBE | YES |
| UNSUBACK | YES |
| PINGREQ | NO |
| PINGRESP | NO |
| DISCONNECT | NO |
برخی از پكتهای کنترلی MQTT حاوی یک Payload به عنوان قسمت نهایی پكت هستند. جدول زیر پكتهای کنترلی را که به Payload نیاز دارند را فهرست كرده است.
| Control Packet | Payload |
| CONNECT | Required |
| CONNACK | None |
| PUBLISH | Optional |
| PUBACK | None |
| PUBREC | None |
| PUBREL | None |
| PUBCOMP | None |
| SUBSCRIBE | Required |
| SUBACK | Required |
| UNSUBSCRIBE | Required |
| UNSUBACK | None |
| PINGREQ | None |
| PINGRESP | None |
| DISCONNECT | None |
نتیجهگیری:
پروتکل MQTT با ساختار ساده اما منعطف خود، یکی از بهترین گزینهها برای پیادهسازی ارتباطات کممصرف و قابل اطمینان در پروژههای اینترنت اشیاء محسوب میشود. درک عمیق از ساختار پکتها، نقش پرچمها و نحوه مدیریت نشستها، به توسعهدهندگان کمک میکند تا عملکرد بهینه و امنی را در سیستمهای خود پیادهسازی کنند.
سوالات متداول
آیا MQTT امن است؟
بهصورت پیشفرض امنیت در سطح پروتکل MQTT ساده است، اما میتوان از TLS و مکانیزمهای احراز هویت (Authentication) برای امنسازی ارتباطات استفاده کرد.
تفاوت QoS 0، 1 و 2 در MQTT چیست؟
QoS 0 پیام را یکبار ارسال میکند بدون تضمین دریافت، QoS 1 پیام را تا دریافت تایید ارسال میکند، QoS 2 حداکثر تضمین را با استفاده از چهار مرحله ارسال و تایید فراهم میکند.
MQTT بهتر است یا HTTP؟
MQTT برای ارتباطات سبک و زمانواقعی در شبکههای IoT مناسبتر است، در حالیکه HTTP برای انتقال دادههای حجیم و ساختار یافته کاربرد دارد.
آیا میتوان از MQTT در شبکههای بدون اینترنت استفاده کرد؟
بله، MQTT در شبکههای محلی (LAN) یا با استفاده از بروکرهای محلی نیز قابل استفاده است.
